/** * * @param string $query * @return array of integers - taskIds */ public static function searchTasks($query) { $fieldWeights = array('description' => 10, 'note' => 6); $indexName = 'plancake_tasks'; $client = new SphinxClient(); // $client->SetServer (sfConfig::get('app_sphinx_host'), sfConfig::get('app_sphinx_port')); $client->SetFilter("author_id", array(PcUserPeer::getLoggedInUser()->getId())); $client->SetConnectTimeout(1); $client->SetMatchMode(SPH_MATCH_ANY); $client->SetSortMode(SPH_SORT_RELEVANCE); $client->SetRankingMode(SPH_RANK_PROXIMITY_BM25); $client->SetArrayResult(true); $client->SetFieldWeights($fieldWeights); $client->setLimits(0, 100); $results = $client->query($client->EscapeString($query), $indexName); if ($results === false) { $error = "Sphinx Error - " . $client->GetLastError(); sfErrorNotifier::alert($error); } $ids = array(); if (isset($results['matches']) && count($results['matches'])) { foreach ($results['matches'] as $match) { $ids[] = $match['id']; } } return PcTaskPeer::retrieveByPKs($ids); }
function hook_search($search) { $offset = 0; $limit = 500; $sphinxClient = new SphinxClient(); $sphinxpair = explode(":", SPHINX_SERVER, 2); $sphinxClient->SetServer($sphinxpair[0], (int) $sphinxpair[1]); $sphinxClient->SetConnectTimeout(1); $sphinxClient->SetFieldWeights(array('title' => 70, 'content' => 30, 'feed_title' => 20)); $sphinxClient->SetMatchMode(SPH_MATCH_EXTENDED2); $sphinxClient->SetRankingMode(SPH_RANK_PROXIMITY_BM25); $sphinxClient->SetLimits($offset, $limit, 1000); $sphinxClient->SetArrayResult(false); $sphinxClient->SetFilter('owner_uid', array($_SESSION['uid'])); $result = $sphinxClient->Query($search, SPHINX_INDEX); $ids = array(); if (is_array($result['matches'])) { foreach (array_keys($result['matches']) as $int_id) { $ref_id = $result['matches'][$int_id]['attrs']['ref_id']; array_push($ids, $ref_id); } } $ids = join(",", $ids); if ($ids) { return array("ref_id IN ({$ids})", array()); } else { return array("ref_id = -1", array()); } }
private function institutions($data) { $q = $this->getRequestParameter("q", ''); if (!$q) { throw new BadRequestException('A search string must be provided.'); } $page = $this->getRequestParameter("page", '1'); $limit = $this->getRequestParameter("limit", self::PAGE_SIZE); $culture = $this->getRequestParameter("culture", 'es'); $type = $this->getRequestParameter("type", false); $this->getUser()->setCulture($culture); $cl = new SphinxClient(); $dbConf = Propel::getConfiguration(); $dsn = $dbConf['datasources']['propel']['connection']['dsn']; $sphinxServer = sfConfig::get('sf_sphinx_server'); $cl->SetServer($sphinxServer, 3312); $this->limit = 1000; $cl->SetLimits(0, $this->limit, $this->limit); $cl->SetArrayResult(true); #instituciones $this->res = $cl->Query($q, "institucion_{$culture}"); $cl->SetFieldWeights(array('vanity' => 5)); $cl->SetSortMode(SPH_SORT_RELEVANCE); $institutions = array(); if ($this->res !== false) { if (isset($this->res["matches"]) && is_array($this->res["matches"])) { $c = new Criteria(); $list = array(); foreach ($this->res["matches"] as $idx => $match) { $list[] = $match['id']; } $c->add(InstitucionPeer::ID, $list, Criteria::IN); $c->addAscendingOrderByColumn(InstitucionPeer::ORDEN); //$instituciones = InstitucionPeer::doSelect($c); $pager = new sfPropelPager('Institucion', $limit); $pager->setCriteria($c); $pager->setPage($this->getRequestParameter('page', $page)); $pager->init(); foreach ($pager->getResults() as $aInstitution) { $institution = new Institution(); $institution->setId($aInstitution->getId()); $institution->setVanity($aInstitution->getVanity()); $institution->setName($aInstitution->getNombreCorto()); $institution->setLongName($aInstitution->getNombre()); $institutions[] = $institution; } } } return $institutions; }
/** * @{inheritDoc} */ public function set_keywords($keywords, $search_title, $search_text) { $this->keywords = $this->clean_string($keywords); if (!$search_title && $search_text) { $this->client->SetFieldWeights(array('title' => 1, 'data' => 5)); $this->search_query_prefix = '@data '; } else { if ($search_title && !$search_text) { $this->client->SetFieldWeights(array('title' => 5, 'data' => 1)); $this->search_query_prefix = '@title '; } } return $this; }
protected function resetClient() { $this->sphinxClient->ResetFilters(); $this->sphinxClient->ResetGroupBy(); $this->sphinxClient->ResetOverrides(); $this->sphinxClient->SetLimits(0, 20); $this->sphinxClient->SetArrayResult(true); $this->sphinxClient->SetFieldWeights(array()); $this->sphinxClient->SetIDRange(0, 0); $this->sphinxClient->SetIndexWeights(array()); $this->sphinxClient->SetMatchMode(SPH_MATCH_EXTENDED2); $this->sphinxClient->SetRankingMode(SPH_RANK_NONE); $this->sphinxClient->SetSortMode(SPH_SORT_RELEVANCE, ""); $this->sphinxClient->SetSelect("*"); }
function draw2() { $keywords = AZLib::getParam('keywords'); $total_item = 0; $search_result = false; $items = array(); $paging = ''; $cmd = ''; $cat_search_id = 0; $item_array = array(); $listCat = array(); if ($keywords) { //AZLib::getCats(); require "./includes/sphinxapi.class.php"; foreach (CGlobal::$allCategories as $value) { if ($value['parent_id'] == 0) { $cat_list[$value['id']] = $value['brief_name']; } } $category = $this->getTotalPerCategory($keywords); foreach ($category as $row) { $row['brief_name'] = isset($cat_list[$row['level_1_catid']]) && $cat_list[$row['level_1_catid']] ? $cat_list[$row['level_1_catid']] : "Khác"; $listCat[$row['level_1_catid']] = array("level_1_catid" => $row["level_1_catid"], "brief_name" => $row['brief_name'], "count_ad" => $row['@count']); } $total = 0; $catid = 0; $catActive = ''; $total_cat = 0; if ($listCat) { $first_val = array_slice($listCat, 0, 1); $total = $first_val[0]['count_ad']; $catid = $first_val[0]['level_1_catid']; $catActive = $first_val[0]['brief_name']; $total_cat = count($listCat); } $i = 0; $allrecord = 0; $otherCat = ''; $cat_content = ""; foreach ($listCat as $cat) { if ($i < 3) { $active = $i == 0 ? "class=\"active\"" : ""; $cat_content .= "<li id=\"tab_{$i}\" {$active} onclick=\"javascript:acive_tab_cat(this);\"><a href=\"javascript:void(0);\" onclick=\"javascript:search_cat({$cat['level_1_catid']},{$cat['count_ad']},1,0);\"><span id=\"kby_{$cat['level_1_catid']}\">" . $cat['brief_name'] . " <font style=\"color: #5a7e92;font-weight: normal;\">(" . $cat['count_ad'] . ")</font></span></a></li>"; } else { $otherCat .= "<div class=\"other\"><a href=\"javascript:void(0);\" onclick=\"javascript:search_cat({$cat['level_1_catid']},{$cat['count_ad']},1,0);acive_tab_cat(this);\" id=\"tab_{$i}\"><span id=\"kby_{$cat['level_1_catid']}\">" . $cat['brief_name'] . " <font style=\"color: #5a7e92;font-weight: normal;\">(" . $cat['count_ad'] . ")</font></span></a></div>"; } $i++; $allrecord = $allrecord + $cat['count_ad']; } $display->add("cat_content", $cat_content); $display->add("CatActiveId", $catid); $display->add("catActive", $catActive); $display->add("listCat", $listCat); $display->add("allrecord", $allrecord); $display->add("otherCat", str_replace(array(chr(13), chr(10)), "", $otherCat)); $display->add("total_cat", $total_cat); //Init for sphinx search paging $pager = new Pager(); //config $limit = SEARCH_LIMIT; $pager->type = "search"; $pager->catid = $catid; $pager->total = $total; $pager->limit = $limit; $pager->page_param = 'page'; $pager->page = 1; $offset = $pager->get_offset(); $limit_from = $pager->limit_from(); $limit_to = $pager->limit_to(); //Sphinx search by Nova $q = $keywords; $mode = SPH_MATCH_EXTENDED2; //Init config $host = SPHINX_SERVER; $port = SPHINX_PORT; //$index = SPHINX_INDEX; $index = "enbac delta"; $filtervals = array(); $ranker = SPH_RANK_WORDCOUNT; $cl = new SphinxClient(); $cl->SetServer($host, $port); $cl->SetConnectTimeout(1); $cl->SetWeights(array(100, 1)); $cl->SetMatchMode($mode); //filter if ($catid) { $cl->SetFilter('level_1_catid', array($catid)); } $cl->SetFilter('status', array('1')); $cl->SetFieldWeights(array('user_name' => 10000, 'name' => 1000, 'description' => 1)); //$cl->SetSortMode( SPH_SORT_EXTENDED, 'up_time DESC' ); //$cl->SetSortMode( SPH_SORT_RELEVANCE);//Sort theo kq chính xác nhất //$cl->SetSortMode ( SPH_SORT_EXPR, "@weight + ( user_karma + ln(pageviews) )*0.1"); $cl->SetSortMode(SPH_SORT_EXPR, "@weight"); //Sort theo trọng số //SPH_RANK_WORDCOUNT //SPH_MATCH_EXTENDED2 //end filter $cl->SetLimits($offset, $limit, 10000); $cl->SetRankingMode($ranker); $cl->SetArrayResult(true); $res = $cl->Query($q, $index); /*echo '<pre>'; print_r($res["matches"]);*/ if ($res && isset($res["matches"])) { if (is_array($res["matches"])) { foreach ($res["matches"] as $results) { $list_item_id[] = $results['id']; } } $comma_separated = join(",", $list_item_id); } if ($total) { if ($limit_to > $total) { $limit_to = $total; } $comma_separated = join(",", $list_item_id); if ($comma_separated) { //$sql = "SELECT id,name,up_time,price,user_id,user_name, level_1_catid,category_id,description,img_url, img_server FROM item WHERE id IN($comma_separated) AND status=1 ORDER BY up_time DESC"; //$sql = "SELECT id,name,up_time,price,user_id,user_name, level_1_catid,category_id,description,img_url, img_server FROM item WHERE id IN($comma_separated) AND status=1 AND state=0 ORDER BY find_in_set(id,'$comma_separated')"; $sql = "SELECT id,name,up_time,price,user_id,user_name, level_1_catid,category_id,description,img_url, img_server FROM item WHERE id IN({$comma_separated}) AND status=1 ORDER BY find_in_set(id,'{$comma_separated}')"; $search_result = DB::query($sql); $pager->total = $total; $paging = $pager->page_link(); } } } $highlight = ''; if ($keywords) { $highlight = $str_search = str_replace(array('+', '/', '|', '-', '*'), "", $keywords); $highlight = AZLib::trimSpace($highlight); $highlight = str_replace("'", '', $highlight); $highlight = str_replace("'", '', $highlight); $highlight = str_replace(""", '', $highlight); } $highlight1 = ''; if ($highlight) { $arr = explode(' ', $highlight); if ($arr) { $highlight = ""; foreach ($arr as $word) { $highlight = ($highlight ? $highlight . ', ' : '') . "'{$word}'"; $highlight1 = ($highlight1 ? $highlight1 . ',' : '') . $word; } } } if ($keywords && $search_result) { while ($item = mysql_fetch_assoc($search_result)) { $item['profile_url'] = WEB_DIR . $item['user_name']; $item['name_hl'] = AZLib::HighLightKeyword(strip_tags(AZLib::filter_title($item['name'])), $highlight1); $item_time = TIME_NOW - $item['up_time']; //neu nho hon 1h thi tinh ra phut if ($item_time < 3600) { $item['item_time'] = floor($item_time / 60) . " phút trước đây"; } elseif ($item_time < 86400) { $item['item_time'] = floor($item_time / 3600) . " giờ trước đây"; } else { $item['item_time'] = date('\\n\\gà\\y j \\t\\há\\n\\g n', $item['up_time']); } $item['description'] = AZLib::HighLightKeyword(AZLib::delDoubleSpace(AZLib::trimSpace(strip_tags(AZLib::post_db_parse_html(preg_replace('/\\[[0-9]{1,3}\\]/', '', $item['description']))))), $highlight1, 35, "background:yellow;font-size:14px;font-weight:bold;color:blue;"); $ebname = AZLib::safe_title($item['name']); $ebname_tmp = substr(AZLib::safe_title($item['name']), 0, 20); if (isset(CGlobal::$allCategories[$item['category_id']])) { $item['item_url'] = WEB_DIR . AZRewrite::formatUrl('?page=item_detail&id=' . $item['id'] . '&ebname=' . $ebname . '&nice_name=' . CGlobal::$allCategories[$item['category_id']]['nice_name']); $item['item_url_tmp'] = WEB_ROOT . CGlobal::$allCategories[$item['category_id']]['nice_name'] . '/p' . $item['id'] . '/' . $ebname_tmp . '...'; } else { $item['item_url'] = WEB_DIR . AZRewrite::formatUrl('?page=item_detail&id=' . $item['id'] . '&ebname=' . $ebname); $item['item_url_tmp'] = WEB_ROOT . 'p' . $item['id'] . '/' . $ebname_tmp . '...'; } if ($item['img_url']) { $item['img_url'] = AZLib::getImageThumb($item['img_url'], 110, 0, 1, $item['img_server']); } $item['price'] = number_format($item['price'], 0, ',', '.'); $item_array[] = $item; } } global $start_rb; $mtime = microtime(); $mtime = explode(" ", $mtime); $mtime = $mtime[1] + $mtime[0]; $end_rb = $mtime; $search_time = round($end_rb - $start_rb, 3); $display->add('limit_from', $limit_from); $display->add('limit_to', $limit_to); $display->add('search_time', $search_time); $display->add('keywords', $keywords); $display->add('base_url', WEB_ROOT); $display->add('highlight', $highlight); $display->add('total_item_cat', $total); $display->add('name_item_cat', $catActive); $display->add('block_id', Module::$block_id); $display->add('paging', $paging); $display->add('items', $item_array); $display->output('sphinx_search'); }
/** * Performs a search on keywords depending on display specific params. You have to run split_keywords() first * * @param string $type contains either posts or topics depending on what should be searched for * @param string $fields contains either titleonly (topic titles should be searched), msgonly (only message bodies should be searched), firstpost (only subject and body of the first post should be searched) or all (all post bodies and subjects should be searched) * @param string $terms is either 'all' (use query as entered, words without prefix should default to "have to be in field") or 'any' (ignore search query parts and just return all posts that contain any of the specified words) * @param array $sort_by_sql contains SQL code for the ORDER BY part of a query * @param string $sort_key is the key of $sort_by_sql for the selected sorting * @param string $sort_dir is either a or d representing ASC and DESC * @param string $sort_days specifies the maximum amount of days a post may be old * @param array $ex_fid_ary specifies an array of forum ids which should not be searched * @param string $post_visibility specifies which types of posts the user can view in which forums * @param int $topic_id is set to 0 or a topic id, if it is not 0 then only posts in this topic should be searched * @param array $author_ary an array of author ids if the author should be ignored during the search the array is empty * @param string $author_name specifies the author match, when ANONYMOUS is also a search-match * @param array &$id_ary passed by reference, to be filled with ids for the page specified by $start and $per_page, should be ordered * @param int $start indicates the first index of the page * @param int $per_page number of ids each page is supposed to contain * @return boolean|int total number of results */ public function keyword_search($type, $fields, $terms, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $post_visibility, $topic_id, $author_ary, $author_name, &$id_ary, &$start, $per_page) { // No keywords? No posts. if (!strlen($this->search_query) && !sizeof($author_ary)) { return false; } $id_ary = array(); $join_topic = $type != 'posts'; // Sorting if ($type == 'topics') { switch ($sort_key) { case 'a': $this->sphinx->SetGroupBy('topic_id', SPH_GROUPBY_ATTR, 'poster_id ' . ($sort_dir == 'a' ? 'ASC' : 'DESC')); break; case 'f': $this->sphinx->SetGroupBy('topic_id', SPH_GROUPBY_ATTR, 'forum_id ' . ($sort_dir == 'a' ? 'ASC' : 'DESC')); break; case 'i': case 's': $this->sphinx->SetGroupBy('topic_id', SPH_GROUPBY_ATTR, 'post_subject ' . ($sort_dir == 'a' ? 'ASC' : 'DESC')); break; case 't': default: $this->sphinx->SetGroupBy('topic_id', SPH_GROUPBY_ATTR, 'topic_last_post_time ' . ($sort_dir == 'a' ? 'ASC' : 'DESC')); break; } } else { switch ($sort_key) { case 'a': $this->sphinx->SetSortMode($sort_dir == 'a' ? SPH_SORT_ATTR_ASC : SPH_SORT_ATTR_DESC, 'poster_id'); break; case 'f': $this->sphinx->SetSortMode($sort_dir == 'a' ? SPH_SORT_ATTR_ASC : SPH_SORT_ATTR_DESC, 'forum_id'); break; case 'i': case 's': $this->sphinx->SetSortMode($sort_dir == 'a' ? SPH_SORT_ATTR_ASC : SPH_SORT_ATTR_DESC, 'post_subject'); break; case 't': default: $this->sphinx->SetSortMode($sort_dir == 'a' ? SPH_SORT_ATTR_ASC : SPH_SORT_ATTR_DESC, 'post_time'); break; } } // Most narrow filters first if ($topic_id) { $this->sphinx->SetFilter('topic_id', array($topic_id)); } $search_query_prefix = ''; switch ($fields) { case 'titleonly': // Only search the title if ($terms == 'all') { $search_query_prefix = '@title '; } // Weight for the title $this->sphinx->SetFieldWeights(array("title" => 5, "data" => 1)); // 1 is first_post, 0 is not first post $this->sphinx->SetFilter('topic_first_post', array(1)); break; case 'msgonly': // Only search the body if ($terms == 'all') { $search_query_prefix = '@data '; } // Weight for the body $this->sphinx->SetFieldWeights(array("title" => 1, "data" => 5)); break; case 'firstpost': // More relative weight for the title, also search the body $this->sphinx->SetFieldWeights(array("title" => 5, "data" => 1)); // 1 is first_post, 0 is not first post $this->sphinx->SetFilter('topic_first_post', array(1)); break; default: // More relative weight for the title, also search the body $this->sphinx->SetFieldWeights(array("title" => 5, "data" => 1)); break; } if (sizeof($author_ary)) { $this->sphinx->SetFilter('poster_id', $author_ary); } // As this is not simply possible at the moment, we limit the result to approved posts. // This will make it impossible for moderators to search unapproved and softdeleted posts, // but at least it will also cause the same for normal users. $this->sphinx->SetFilter('post_visibility', array(ITEM_APPROVED)); if (sizeof($ex_fid_ary)) { // All forums that a user is allowed to access $fid_ary = array_unique(array_intersect(array_keys($this->auth->acl_getf('f_read', true)), array_keys($this->auth->acl_getf('f_search', true)))); // All forums that the user wants to and can search in $search_forums = array_diff($fid_ary, $ex_fid_ary); if (sizeof($search_forums)) { $this->sphinx->SetFilter('forum_id', $search_forums); } } $this->sphinx->SetFilter('deleted', array(0)); $this->sphinx->SetLimits($start, (int) $per_page, SPHINX_MAX_MATCHES); $result = $this->sphinx->Query($search_query_prefix . str_replace('"', '"', $this->search_query), $this->indexes); // Could be connection to localhost:9312 failed (errno=111, // msg=Connection refused) during rotate, retry if so $retries = SPHINX_CONNECT_RETRIES; while (!$result && strpos($this->sphinx->GetLastError(), "errno=111,") !== false && $retries--) { usleep(SPHINX_CONNECT_WAIT_TIME); $result = $this->sphinx->Query($search_query_prefix . str_replace('"', '"', $this->search_query), $this->indexes); } if ($this->sphinx->GetLastError()) { add_log('critical', 'LOG_SPHINX_ERROR', $this->sphinx->GetLastError()); if ($this->auth->acl_get('a_')) { trigger_error($this->user->lang('SPHINX_SEARCH_FAILED', $this->sphinx->GetLastError())); } else { trigger_error($this->user->lang('SPHINX_SEARCH_FAILED_LOG')); } } $result_count = $result['total_found']; if ($result_count && $start >= $result_count) { $start = floor(($result_count - 1) / $per_page) * $per_page; $this->sphinx->SetLimits((int) $start, (int) $per_page, SPHINX_MAX_MATCHES); $result = $this->sphinx->Query($search_query_prefix . str_replace('"', '"', $this->search_query), $this->indexes); // Could be connection to localhost:9312 failed (errno=111, // msg=Connection refused) during rotate, retry if so $retries = SPHINX_CONNECT_RETRIES; while (!$result && strpos($this->sphinx->GetLastError(), "errno=111,") !== false && $retries--) { usleep(SPHINX_CONNECT_WAIT_TIME); $result = $this->sphinx->Query($search_query_prefix . str_replace('"', '"', $this->search_query), $this->indexes); } } $id_ary = array(); if (isset($result['matches'])) { if ($type == 'posts') { $id_ary = array_keys($result['matches']); } else { foreach ($result['matches'] as $key => $value) { $id_ary[] = $value['attrs']['topic_id']; } } } else { return false; } $id_ary = array_slice($id_ary, 0, (int) $per_page); return $result_count; }
/** * Does an index search via Sphinx and returns the results * * @param string $type Search type. Valid types are: author, title, series, subject, keyword (default) * @param string $term Search term/phrase * @param int $limit Number of results to return * @param int $offset Where to begin result set -- for pagination purposes * @param array $sort_array Numerically keyed array of sort parameters. Valid options are: newest, oldest * @param array $location_array Numerically keyed array of location params. NOT IMPLEMENTED YET * @param array $facet_args String-keyed array of facet parameters. See code below for array structure * @return array String-keyed result set */ public function search($type, $term, $limit, $offset, $sort_opt = NULL, $format_array = array(), $location_array = array(), $facet_args = array(), $override_search_filter = FALSE, $limit_available = FALSE, $show_inactive = FALSE) { if (is_callable(array(__CLASS__ . '_hook', __FUNCTION__))) { eval('$hook = new ' . __CLASS__ . '_hook;'); return $hook->{__FUNCTION__}($type, $term, $limit, $offset, $sort_opt, $format_array, $location_array, $facet_args, $override_search_filter, $limit_available); } require_once $this->locum_config['sphinx_config']['api_path'] . '/sphinxapi.php'; $db =& MDB2::connect($this->dsn); $term_arr = explode('?', trim(preg_replace('/\\//', ' ', $term))); $term = trim($term_arr[0]); if ($term == '*' || $term == '**') { $term = ''; } else { $term_prestrip = $term; //$term = preg_replace('/[^A-Za-z0-9*\- ]/iD', '', $term); $term = preg_replace('/\\*\\*/', '*', $term); //fix for how iii used to do wildcards } $final_result_set['term'] = $term; $final_result_set['type'] = trim($type); $cl = new SphinxClient(); $cl->SetServer($this->locum_config['sphinx_config']['server_addr'], (int) $this->locum_config['sphinx_config']['server_port']); // Defaults to 'keyword', non-boolean $bool = FALSE; $cl->SetMatchMode(SPH_MATCH_ALL); if (!$term) { // Searches for everything (usually for browsing purposes--Hot/New Items, etc..) $cl->SetMatchMode(SPH_MATCH_EXTENDED2); } else { $picturebook = array('picturebook', 'picture book'); $picbk_search = '(@callnum ^E)'; $term = str_ireplace($picturebook, $picbk_search, $term); if ($type == 'keyword') { // Custom fiction and non-fiction search $nonfic_search = ' (@callnum "0*" | @callnum "1*" | @callnum "2*" | @callnum "3*" | @callnum "4*" | @callnum "5*" | @callnum "6*" | @callnum "7*" | @callnum "8*" | @callnum "9*")'; $fiction_search = ' (@title fiction | @subjects fiction | @callnum mystery | @callnum fantasy | @callnum fiction | @callnum western | @callnum romance)'; if (stripos($term, 'nonfiction') !== FALSE) { $term = '@@relaxed ' . str_ireplace('nonfiction', '', $term) . $nonfic_search; } else { if (strpos($term, 'non-fiction') !== FALSE) { $term = '@@relaxed ' . str_ireplace('non-fiction', '', $term) . $nonfic_search; } else { if (strpos($term, 'fiction') !== FALSE) { $term = '@@relaxed ' . str_ireplace('fiction', '', $term) . $fiction_search; } } } } // Is it a boolean search? if (preg_match("/ \\| /i", $term) || preg_match("/ \\-/i", $term) || preg_match("/ \\!/i", $term)) { $cl->SetMatchMode(SPH_MATCH_BOOLEAN); $bool = TRUE; } if (preg_match("/ OR /i", $term)) { $cl->SetMatchMode(SPH_MATCH_BOOLEAN); $term = preg_replace('/ OR /i', ' | ', $term); $bool = TRUE; } // Is it a phrase search? if (preg_match("/\"/i", $term) || preg_match("/\\@/i", $term)) { $cl->SetMatchMode(SPH_MATCH_EXTENDED2); $bool = TRUE; } } // Set up for the various search types switch ($type) { case 'author': $cl->SetFieldWeights(array('author' => 50, 'addl_author' => 30)); $idx = 'bib_items_author'; break; case 'title': $cl->SetFieldWeights(array('title' => 50, 'title_medium' => 50, 'series' => 30)); $idx = 'bib_items_title'; break; case 'series': $cl->SetFieldWeights(array('title' => 5, 'series' => 80)); $idx = 'bib_items_title'; break; case 'subject': $idx = 'bib_items_subject'; break; case 'callnum': $cl->SetFieldWeights(array('callnum' => 100)); $idx = 'bib_items_callnum'; //$cl->SetMatchMode(SPH_MATCH_ANY); break; case 'tags': $cl->SetFieldWeights(array('tag_idx' => 100)); $idx = 'bib_items_tags'; //$cl->SetMatchMode(SPH_MATCH_PHRASE); break; case 'reviews': $cl->SetFieldWeights(array('review_idx' => 100)); $idx = 'bib_items_reviews'; break; case 'keyword': default: $cl->SetFieldWeights(array('title' => 400, 'title_medium' => 30, 'author' => 70, 'addl_author' => 40, 'tag_idx' => 25, 'series' => 25, 'review_idx' => 10, 'notes' => 10, 'subjects' => 5)); $idx = 'bib_items_keyword'; break; } // Filter out the records we don't want shown, per locum.ini if (!$override_search_filter) { if (trim($this->locum_config['location_limits']['no_search'])) { $cfg_filter_arr = $this->csv_parser($this->locum_config['location_limits']['no_search']); foreach ($cfg_filter_arr as $cfg_filter) { $cfg_filter_vals[] = $this->string_poly($cfg_filter); } $cl->SetFilter('loc_code', $cfg_filter_vals, TRUE); } } // Valid sort types are 'newest' and 'oldest'. Default is relevance. switch ($sort_opt) { case 'newest': $cl->SetSortMode(SPH_SORT_EXTENDED, 'pub_year DESC, @relevance DESC'); break; case 'oldest': $cl->SetSortMode(SPH_SORT_EXTENDED, 'pub_year ASC, @relevance DESC'); break; case 'catalog_newest': $cl->SetSortMode(SPH_SORT_EXTENDED, 'bib_created DESC, @relevance DESC'); break; case 'catalog_oldest': $cl->SetSortMode(SPH_SORT_EXTENDED, 'bib_created ASC, @relevance DESC'); break; case 'title': $cl->SetSortMode(SPH_SORT_ATTR_ASC, 'title_ord'); break; case 'author': $cl->SetSortMode(SPH_SORT_EXTENDED, 'author_null ASC, author_ord ASC'); break; case 'top_rated': $cl->SetSortMode(SPH_SORT_ATTR_DESC, 'rating_idx'); break; case 'popular_week': $cl->SetSortMode(SPH_SORT_ATTR_DESC, 'hold_count_week'); break; case 'popular_month': $cl->SetSortMode(SPH_SORT_ATTR_DESC, 'hold_count_month'); break; case 'popular_year': $cl->SetSortMode(SPH_SORT_ATTR_DESC, 'hold_count_year'); break; case 'popular_total': $cl->SetSortMode(SPH_SORT_ATTR_DESC, 'hold_count_total'); break; case 'atoz': $cl->SetSortMode(SPH_SORT_ATTR_ASC, 'title_ord'); break; case 'ztoa': $cl->SetSortMode(SPH_SORT_ATTR_DESC, 'title_ord'); break; default: $cl->SetSortMode(SPH_SORT_EXPR, "@weight + (hold_count_total)*0.02"); break; } // Filter by material types if (is_array($format_array)) { foreach ($format_array as $format) { if (strtolower($format) != 'all') { $filter_arr_mat[] = $this->string_poly(trim($format)); } } if (count($filter_arr_mat)) { $cl->SetFilter('mat_code', $filter_arr_mat); } } // Filter by location if (count($location_array)) { foreach ($location_array as $location) { if (strtolower($location) != 'all') { $filter_arr_loc[] = $this->string_poly(trim($location)); } } if (count($filter_arr_loc)) { $cl->SetFilter('loc_code', $filter_arr_loc); } } // Filter by pub_year if ($facet_args['facet_year']) { if (strpos($facet_args['facet_year'][0], '-') !== FALSE) { $min_year = 1; $max_year = 9999; $args = explode('-', $facet_args['facet_year'][0]); $min_arg = (int) $args[0]; $max_arg = (int) $args[1]; if ($min_arg && $min_arg > $min_year) { $min_year = $min_arg; } if ($max_arg && $max_arg < $max_year) { $max_year = $max_arg; } $cl->setFilterRange('pub_year', $min_year, $max_year); } else { $cl->SetFilter('pub_year', $facet_args['facet_year']); } } // Filter by pub_decade if ($facet_args['facet_decade']) { $cl->SetFilter('pub_decade', $facet_args['facet_decade']); } // Filter by lexile if ($facet_args['facet_lexile']) { $cl->SetFilter('lexile', $facet_args['facet_lexile']); } // Filter by Series if (count($facet_args['facet_series'])) { foreach ($facet_args['facet_series'] as &$facet_series) { $facet_series = $this->string_poly($facet_series); } $cl->SetFilter('series_attr', $facet_args['facet_series']); } // Filter by Language if (count($facet_args['facet_lang'])) { foreach ($facet_args['facet_lang'] as &$facet_lang) { $facet_lang = $this->string_poly($facet_lang); } $cl->SetFilter('lang', $facet_args['facet_lang']); } // Filter inactive records if (!$show_inactive) { $cl->SetFilter('active', array('0'), TRUE); } // Filter by age if (count($facet_args['age'])) { foreach ($facet_args['age'] as $age_facet) { $cl->SetFilter('ages', array($this->string_poly($age_facet))); } } // Filter by availability if ($limit_available) { $cl->SetFilter('branches', array($this->string_poly($limit_available))); } $cl->SetRankingMode(SPH_RANK_SPH04); $proximity_check = $cl->Query($term, $idx); // Quick check on number of results // If original match didn't return any results, try a proximity search if (empty($proximity_check['matches']) && $bool == FALSE && $term != "*" && $type != "tags") { $term = '"' . $term . '"/1'; $cl->SetMatchMode(SPH_MATCH_EXTENDED); $forcedchange = 'yes'; } // Paging/browsing through the result set. $sort_limit = 2000; if ($offset + $limit > $sort_limit) { $sort_limit = $offset + $limit; } $cl->SetLimits((int) $offset, (int) $limit, (int) $sort_limit); // And finally.... we search. $cl->AddQuery($term, $idx); // CREATE FACETS $cl->SetLimits(0, 1000); // Up to 1000 facets $cl->SetArrayResult(TRUE); // Allow duplicate documents in result, for facet grouping $cl->SetGroupBy('pub_year', SPH_GROUPBY_ATTR); $cl->AddQuery($term, $idx); $cl->ResetGroupBy(); $cl->SetGroupBy('pub_decade', SPH_GROUPBY_ATTR); $cl->AddQuery($term, $idx); $cl->ResetGroupBy(); $cl->SetGroupBy('mat_code', SPH_GROUPBY_ATTR, '@count desc'); $cl->AddQuery($term, $idx); $cl->ResetGroupBy(); $cl->SetGroupBy('branches', SPH_GROUPBY_ATTR, '@count desc'); $cl->AddQuery($term, $idx); $cl->ResetGroupBy(); $cl->SetGroupBy('ages', SPH_GROUPBY_ATTR, '@count desc'); $cl->AddQuery($term, $idx); $cl->ResetGroupBy(); $cl->SetGroupBy('lang', SPH_GROUPBY_ATTR, '@count desc'); $cl->AddQuery($term, $idx); $cl->ResetGroupBy(); $cl->SetGroupBy('series_attr', SPH_GROUPBY_ATTR, '@count desc'); $cl->AddQuery($term, $idx); $cl->ResetGroupBy(); $cl->SetGroupBy('lexile', SPH_GROUPBY_ATTR); $cl->AddQuery($term, $idx); $cl->ResetGroupBy(); $results = $cl->RunQueries(); // Include descriptors $final_result_set['num_hits'] = $results[0]['total_found']; if ($results[0]['total'] <= $this->locum_config['api_config']['suggestion_threshold'] || $forcedchange == 'yes') { if ($this->locum_config['api_config']['use_yahoo_suggest'] == TRUE) { $final_result_set['suggestion'] = $this->yahoo_suggest($term_prestrip); } } // Pull full records out of Couch if ($final_result_set['num_hits']) { $skip_avail = $this->csv_parser($this->locum_config['format_special']['skip_avail']); $bib_hits = array(); foreach ($results[0]['matches'] as $match) { $bib_hits[] = (string) $match['id']; } $final_result_set['results'] = $this->get_bib_items_arr($bib_hits); foreach ($final_result_set['results'] as &$result) { $result = $result['value']; if ($result['bnum']) { // Get availability (Only cached) $result['status'] = $this->get_item_status($result['bnum'], FALSE, TRUE); } } } $final_result_set['facets'] = $this->sphinx_facetizer($results); if ($forcedchange == 'yes') { $final_result_set['changed'] = 'yes'; } return $final_result_set; }
require DISCUZ_ROOT . './include/sphinxapi.php'; $sp_host = '192.168.0.120'; $sp_port = 3312; $cl = new SphinxClient(); //设置服务器 $cl->SetServer($sp_host, $sp_port); //设置搜索模式(处理空格的和关系) if (preg_match('|\\s+|', $key)) { $cl->SetMatchMode(SPH_MATCH_ALL); } else { $cl->SetMatchMode(SPH_MATCH_PHRASE); } if ($srchtype == 'fulltext') { //设置个字段权重 $weight = array('subject' => 70, 'message' => 30); $cl->SetFieldWeights($weight); $sp_index = 'dzbbs;dzbbs_delta'; $sp_hightlight_index = 'dzbbs'; } else { $weight = array('subject' => 100); $sp_index = 'threads;threads_delta'; $sp_hightlight_index = 'threads'; } $cl->SetFieldWeights($weight); //帖子作者 if (!empty($srchuid)) { $cl->setfilter('authorid', array($srchuid)); } if ($srchtype == 'title') { //特殊主题: 投票主题 商品主题 悬赏主题 活动主题 辩论主题 视频主题 $sp_special_filter = array(1, 2, 3, 4, 5, 6);
/** * Performs a search on keywords depending on display specific params. You have to run split_keywords() first * * @param string $type contains either posts or topics depending on what should be searched for * @param string $fields contains either titleonly (topic titles should be searched), msgonly (only message bodies should be searched), firstpost (only subject and body of the first post should be searched) or all (all post bodies and subjects should be searched) * @param string $terms is either 'all' (use query as entered, words without prefix should default to "have to be in field") or 'any' (ignore search query parts and just return all posts that contain any of the specified words) * @param array $sort_by_sql contains SQL code for the ORDER BY part of a query * @param string $sort_key is the key of $sort_by_sql for the selected sorting * @param string $sort_dir is either a or d representing ASC and DESC * @param string $sort_days specifies the maximum amount of days a post may be old * @param array $ex_fid_ary specifies an array of forum ids which should not be searched * @param string $post_visibility specifies which types of posts the user can view in which forums * @param int $topic_id is set to 0 or a topic id, if it is not 0 then only posts in this topic should be searched * @param array $author_ary an array of author ids if the author should be ignored during the search the array is empty * @param string $author_name specifies the author match, when ANONYMOUS is also a search-match * @param array &$id_ary passed by reference, to be filled with ids for the page specified by $start and $per_page, should be ordered * @param int $start indicates the first index of the page * @param int $per_page number of ids each page is supposed to contain * @return boolean|int total number of results */ public function keyword_search($type, $fields, $terms, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $post_visibility, $topic_id, $author_ary, $author_name, &$id_ary, &$start, $per_page) { global $user, $phpbb_log; // No keywords? No posts. if (!strlen($this->search_query) && !sizeof($author_ary)) { return false; } $id_ary = array(); // Sorting if ($type == 'topics') { switch ($sort_key) { case 'a': $this->sphinx->SetGroupBy('topic_id', SPH_GROUPBY_ATTR, 'poster_id ' . ($sort_dir == 'a' ? 'ASC' : 'DESC')); break; case 'f': $this->sphinx->SetGroupBy('topic_id', SPH_GROUPBY_ATTR, 'forum_id ' . ($sort_dir == 'a' ? 'ASC' : 'DESC')); break; case 'i': case 's': $this->sphinx->SetGroupBy('topic_id', SPH_GROUPBY_ATTR, 'post_subject ' . ($sort_dir == 'a' ? 'ASC' : 'DESC')); break; case 't': default: $this->sphinx->SetGroupBy('topic_id', SPH_GROUPBY_ATTR, 'topic_last_post_time ' . ($sort_dir == 'a' ? 'ASC' : 'DESC')); break; } } else { switch ($sort_key) { case 'a': $this->sphinx->SetSortMode($sort_dir == 'a' ? SPH_SORT_ATTR_ASC : SPH_SORT_ATTR_DESC, 'poster_id'); break; case 'f': $this->sphinx->SetSortMode($sort_dir == 'a' ? SPH_SORT_ATTR_ASC : SPH_SORT_ATTR_DESC, 'forum_id'); break; case 'i': case 's': $this->sphinx->SetSortMode($sort_dir == 'a' ? SPH_SORT_ATTR_ASC : SPH_SORT_ATTR_DESC, 'post_subject'); break; case 't': default: $this->sphinx->SetSortMode($sort_dir == 'a' ? SPH_SORT_ATTR_ASC : SPH_SORT_ATTR_DESC, 'post_time'); break; } } // Most narrow filters first if ($topic_id) { $this->sphinx->SetFilter('topic_id', array($topic_id)); } /** * Allow modifying the Sphinx search options * * @event core.search_sphinx_keywords_modify_options * @var string type Searching type ('posts', 'topics') * @var string fields Searching fields ('titleonly', 'msgonly', 'firstpost', 'all') * @var string terms Searching terms ('all', 'any') * @var int sort_days Time, in days, of the oldest possible post to list * @var string sort_key The sort type used from the possible sort types * @var int topic_id Limit the search to this topic_id only * @var array ex_fid_ary Which forums not to search on * @var string post_visibility Post visibility data * @var array author_ary Array of user_id containing the users to filter the results to * @var string author_name The username to search on * @var object sphinx The Sphinx searchd client object * @since 3.1.7-RC1 */ $sphinx = $this->sphinx; $vars = array('type', 'fields', 'terms', 'sort_days', 'sort_key', 'topic_id', 'ex_fid_ary', 'post_visibility', 'author_ary', 'author_name', 'sphinx'); extract($this->phpbb_dispatcher->trigger_event('core.search_sphinx_keywords_modify_options', compact($vars))); $this->sphinx = $sphinx; unset($sphinx); $search_query_prefix = ''; switch ($fields) { case 'titleonly': // Only search the title if ($terms == 'all') { $search_query_prefix = '@title '; } // Weight for the title $this->sphinx->SetFieldWeights(array("title" => 5, "data" => 1)); // 1 is first_post, 0 is not first post $this->sphinx->SetFilter('topic_first_post', array(1)); break; case 'msgonly': // Only search the body if ($terms == 'all') { $search_query_prefix = '@data '; } // Weight for the body $this->sphinx->SetFieldWeights(array("title" => 1, "data" => 5)); break; case 'firstpost': // More relative weight for the title, also search the body $this->sphinx->SetFieldWeights(array("title" => 5, "data" => 1)); // 1 is first_post, 0 is not first post $this->sphinx->SetFilter('topic_first_post', array(1)); break; default: // More relative weight for the title, also search the body $this->sphinx->SetFieldWeights(array("title" => 5, "data" => 1)); break; } if (sizeof($author_ary)) { $this->sphinx->SetFilter('poster_id', $author_ary); } // As this is not simply possible at the moment, we limit the result to approved posts. // This will make it impossible for moderators to search unapproved and softdeleted posts, // but at least it will also cause the same for normal users. $this->sphinx->SetFilter('post_visibility', array(ITEM_APPROVED)); if (sizeof($ex_fid_ary)) { // All forums that a user is allowed to access $fid_ary = array_unique(array_intersect(array_keys($this->auth->acl_getf('f_read', true)), array_keys($this->auth->acl_getf('f_search', true)))); // All forums that the user wants to and can search in $search_forums = array_diff($fid_ary, $ex_fid_ary); if (sizeof($search_forums)) { $this->sphinx->SetFilter('forum_id', $search_forums); } } $this->sphinx->SetFilter('deleted', array(0)); $this->sphinx->SetLimits($start, (int) $per_page, SPHINX_MAX_MATCHES); $result = $this->sphinx->Query($search_query_prefix . str_replace('"', '"', $this->search_query), $this->indexes); // Could be connection to localhost:9312 failed (errno=111, // msg=Connection refused) during rotate, retry if so $retries = SPHINX_CONNECT_RETRIES; while (!$result && strpos($this->sphinx->GetLastError(), "errno=111,") !== false && $retries--) { usleep(SPHINX_CONNECT_WAIT_TIME); $result = $this->sphinx->Query($search_query_prefix . str_replace('"', '"', $this->search_query), $this->indexes); } if ($this->sphinx->GetLastError()) { $phpbb_log->add('critical', $user->data['user_id'], $user->ip, 'LOG_SPHINX_ERROR', false, array($this->sphinx->GetLastError())); if ($this->auth->acl_get('a_')) { trigger_error($this->user->lang('SPHINX_SEARCH_FAILED', $this->sphinx->GetLastError())); } else { trigger_error($this->user->lang('SPHINX_SEARCH_FAILED_LOG')); } } $result_count = $result['total_found']; if ($result_count && $start >= $result_count) { $start = floor(($result_count - 1) / $per_page) * $per_page; $this->sphinx->SetLimits((int) $start, (int) $per_page, SPHINX_MAX_MATCHES); $result = $this->sphinx->Query($search_query_prefix . str_replace('"', '"', $this->search_query), $this->indexes); // Could be connection to localhost:9312 failed (errno=111, // msg=Connection refused) during rotate, retry if so $retries = SPHINX_CONNECT_RETRIES; while (!$result && strpos($this->sphinx->GetLastError(), "errno=111,") !== false && $retries--) { usleep(SPHINX_CONNECT_WAIT_TIME); $result = $this->sphinx->Query($search_query_prefix . str_replace('"', '"', $this->search_query), $this->indexes); } } $id_ary = array(); if (isset($result['matches'])) { if ($type == 'posts') { $id_ary = array_keys($result['matches']); } else { foreach ($result['matches'] as $key => $value) { $id_ary[] = $value['attrs']['topic_id']; } } } else { return false; } $id_ary = array_slice($id_ary, 0, (int) $per_page); return $result_count; }
/** * ¬озвращает список публичных типовых услуг по заданным услови¤м и пагинацией * * @return array */ public function getList($excluded_ids = array()) { $criteria = array($this->category_id, $this->city_id, $this->country_id, $this->keywords, $this->limit, $this->offset, $this->price_ranges, $this->price_max, $this->order, $excluded_ids, $this->user_id); $membuf = new memBuff(); $memkey = __METHOD__ . '#' . md5(serialize($criteria)); if (false !== ($result = $membuf->get($memkey)) && is_release()) { return $result; } $sort = $this->getSort(); # @see http://sphinxsearch.com/forum/view.html?id=11538 about city = x or country = y $sphinxClient = new SphinxClient(); $sphinxClient->SetServer(SEARCHHOST, SEARCHPORT); $sphinxClient->SetLimits($this->offset, $this->limit, 20000); $sphinxClient->SetSortMode(SPH_SORT_EXTENDED, $sort); $sphinxClient->SetFieldWeights(array('title' => 2, 'extra_title' => 1)); //$sphinxClient->SetRankingMode(SPH_RANK_PROXIMITY_BM25); $selectExpression = '*'; // все колонки if ($this->user_id) { $selectExpression .= ", IF(user_id = {$this->user_id}, 1, 0) as match_user"; $sphinxClient->setFilter('match_user', array(1)); } if ($this->category_id) { $selectExpression .= ", IF(category_id = {$this->category_id} or category_parent_id = {$this->category_id}, 1, 0) as match_category"; $sphinxClient->setFilter('match_category', array(1)); } if ($this->country_id) { $selectExpression .= ", IF(user_country_id = {$this->country_id} or country_id = {$this->country_id}, 1, 0) as match_country"; $sphinxClient->setFilter('match_country', array(1)); } if ($this->city_id) { $selectExpression .= ", IF(user_city_id = {$this->city_id} or city_id = {$this->city_id}, 1, 0) as match_city"; $sphinxClient->setFilter('match_city', array(1)); } if (count($this->price_ranges)) { $match_price_exprs = array(); foreach ($this->getPriceRanges() as $i => $price_range) { if (!isset($this->price_ranges[$i])) { continue; } $match_price_exprs[] = "price_{$i} = 1"; } $match_price_exprs = implode(' or ', $match_price_exprs); $selectExpression .= ", IF({$match_price_exprs}, 1, 0) as match_price"; $sphinxClient->setFilter('match_price', array(1)); } if ($this->price_max > 0) { $selectExpression .= ", IF(price <= {$this->price_max}, 1, 0) as match_price_max"; $sphinxClient->setFilter('match_price_max', array(1)); } $searchString = ''; if (!empty($this->keywords)) { $keywords = implode(' ', array_filter(preg_split('/\\s*,\\s*/', $this->keywords))); $searchString = trim($keywords); //$searchString = $this->GetSphinxKeyword($searchString); $sphinxClient->SetMatchMode(SPH_MATCH_ANY); //SPH_MATCH_EXTENDED2); } if (count($excluded_ids)) { $sphinxClient->setFilter('tservice_id', $excluded_ids, true); } $sphinxClient->SetSelect($selectExpression); $queryResult = $sphinxClient->query($searchString, "tservices;delta_tservices"); //echo '<pre>error: ', $sphinxClient->GetLastError(), '</pre>'; //echo '<pre>warn : ', $sphinxClient->GetLastWarning(), '</pre>'; $list = array(); $total = 0; if (isset($queryResult['matches'])) { foreach ($queryResult['matches'] as $id => $row) { $row['attrs']['id'] = $id; $list[] = $row['attrs']; } $total = $queryResult['total_found'] < $queryResult['total'] ? $queryResult['total_found'] : $queryResult['total']; } $result = array('list' => $list, 'total' => $total); if ($this->_ttl) { $membuf->set($memkey, $result, $this->_ttl); } return $result; }
<?php require "spec/fixtures/sphinxapi.php"; $cl = new SphinxClient(); $cl->SetFieldWeights(array('field1' => 10, 'field2' => 20)); $cl->Query('query');
/** * 设置字段权重. $weights should look like: * * $weights = array( * 'Normal field name' => 1, * 'Important field name' => 10, * ); * * @param array $weights Array of field weights. */ function setFieldWeights($weights) { $this->sphinx->SetFieldWeights($weights); return $this; }
/** * Фильтр по аббривиатурам * * @Route("/ajax/abbr/{string}", name="ajax_abbr", defaults = {"string" = null}) */ public function letterForAbbriviature(Request $request, $string = null) { if (!$string) { $string = $request->query->get('string'); } $type = $request->query->has('type') ? $request->query->get('type') : 'publication'; $order = $request->query->get('order', '') == 'relevant' ? 'relevant' : 'created'; //$order = $request->query->get('order', '') == 'created' ? 'created' : 'relevant'; $page = $request->query->has('page') ? $request->query->get('page') : $request->query->get('p', 1); $page = intval($page); # удаляем лишние символы и пробелы $string = preg_replace('/[^a-zа-я\\s]/iu', ' ', $string); $string = preg_replace('/\\s+/iu', ' ', $string); $params = array('search' => $string); $params['string'] = $string; $params['type'] = $type; $params['order'] = $order; $params['page'] = $page; $params['currentPage'] = $page; if ($page < 1) { throw $this->createNotFoundException('Incorrect page number: ' . $page); } # удаляем лишние символы из запроса $string = preg_replace('/[^a-zа-я0-9-, :\\.\\(\\)]/iu', '', $string); $string = preg_replace('/[,:\\.\\(\\)]/', ' ', $string); # проверка, есть ли поисковое слово if (mb_strlen(trim($string), 'utf-8') < 2) { return $this->render('EvrikaMainBundle:Search:search_error.html.twig'); } # разбиваем на слова, отсекаем окончания if (!preg_match('/[A-Z]/', $string) && !preg_match('/[А-Я]/u', $string)) { # берем основу слов, если нету собственных имен (заглавных) $string = $this->get('evrika.lingua_stem')->stem_string($string); } # каждое слово дополняется с конца звездочкой (wildcard), разделитеть - ИЛИ $words = explode(' ', $string); # клиентский запрос $s = new \SphinxClient(); $s->SetServer("localhost", 9312); // должна быть запущена служба по порту: searchd --config /c/sphinx/shinx.cnf //$s->SetRankingMode(SPH_RANK_PROXIMITY); $s->SetMatchMode(SPH_MATCH_EXTENDED2); // SPH_MATCH_ALL will match all words in the search term $s->SetArrayResult(true); $s->SetLimits(($page - 1) * self::SEARCH_PER_PAGE, self::SEARCH_PER_PAGE); # получаем результаты поиска if ($order == 'created') { $s->setSortMode(SPH_SORT_EXTENDED, 'created DESC'); } else { $s->SetFieldWeights(array('title' => 10, 'shortText' => 3, 'body' => 1)); $s->SetSortMode('SPH_SORT_EXTENDED', '@weight desc, mydate desc, @id asc'); } # находим публикации по всем введенным словам $query = implode('* &', $words) . '*'; $s_publications = $s->Query("@(title,shortText,body) {$query} & @type=publication", 'publication'); if (!isset($s_publications['matches'])) { # если не нашли - находим по любому из слов $query = implode('* |', $words) . '*'; $s_publications = $s->Query("@(title,shortText,body) {$query} & @type=publication", 'publication'); } # находим события по всем введенным словам $s_events = $s->Query("@(title,shortText,body) {$query} & @type=event", 'publication'); if (!isset($s_events['matches'])) { # если не нашли - находим по любому из слов $query = implode('* |', $words) . '*'; $s_events = $s->Query("@(title,shortText,body) {$query} & @type=event", 'publication'); } # если поймали ошибку $error = $s->GetLastError(); if (!empty($error)) { throw $this->createNotFoundException($error); } # всего публикаций и событий $params['totalPublications'] = intval($s_publications['total']); $params['totalEvents'] = intval($s_events['total']); # заполняем публикации/события из базы данных по полученным ID из запроса Sphinx $publications = array(); $total = $type == 'event' ? $params['totalEvents'] : $params['totalPublications']; # если материалы найдены if ($total) { $em = $this->getDoctrine()->getManager(); $highlight = array('publications' => array(), 'events' => array()); if ($type == 'event') { foreach ($s_events['matches'] as $o) { if ($publication = $em->getRepository('EvrikaMainBundle:Event')->findEnabledById($o['id'] - 1000000)) { $publications[] = $publication; } } } else { foreach ($s_publications['matches'] as $o) { if ($publication = $em->getRepository('EvrikaMainBundle:Publication')->findEnabledById($o['id'])) { $publications[] = $publication; } } } # надо сделать подсветку частей с найденными словами $words = explode(' ', $string); $rep = array('$1<span class="yellow">$2</span>', '<span class="yellow">$0</span>'); for ($i = 0; $i < count($publications); $i++) { $id = $publications[$i]->getId() . ''; $title = $publications[$i]->getTitle(); $shortText = $publications[$i]->getShortText(); $isEvent = $publications[$i]->isEvent(); foreach ($words as $word) { if (!empty($word)) { $pat = array('/([ ,>\\.\\-])(' . $word . '[a-zа-я]*)/iu', '/^' . $word . '[a-zа-я]*/iu'); $title = preg_replace($pat, $rep, $title); if (!$isEvent) { $shortText = preg_replace($pat, $rep, $shortText); } } } if ($isEvent) { $highlight['events'][$id]['title'] = $title; } else { $highlight['publications'][$id]['title'] = $title; $highlight['publications'][$id]['shortText'] = $shortText; } } $params['highlight'] = $highlight; } # смотрим препараты $emDrug = $this->getDoctrine()->getManager('drug'); list($products, $anyOfWord) = $emDrug->getRepository('VidalDrugBundle:Product')->findByQuery($string, false); if (!empty($products)) { $params['totalProducts'] = count($products); if ($type == 'product') { $productIds = array(); foreach ($products as $product) { $productIds[] = $product['ProductID']; } $pagination = $this->get('knp_paginator')->paginate($products, $page, self::PRODUCTS_PER_PAGE); $params['productsPagination'] = $pagination; $params['anyOfWord'] = $anyOfWord; $params['companies'] = $emDrug->getRepository('VidalDrugBundle:Company')->findByProducts($productIds); $params['pictures'] = $emDrug->getRepository('VidalDrugBundle:Picture')->findByProductIds($productIds, date('Y')); $params['infoPages'] = $emDrug->getRepository('VidalDrugBundle:InfoPage')->findByProducts($pagination); } } # смотрим федеральные стандарты $em = $this->getDoctrine()->getManager(); $standarts = $em->getRepository('EvrikaMainBundle:Standart')->findByQuery($string); if (!empty($standarts)) { $params['totalStandarts'] = count($standarts); if ($type == 'standart') { $params['standarts'] = $standarts; } } $params['feedType'] = 'search'; $params['category'] = 'all'; $params['displayedPages'] = self::DISPLAYED_PAGES; $params['bookmarks'] = $this->get('evrika.session_manager')->getBookmarks(); $params['type'] = $type; $params['total'] = $total; $params['numberOfPages'] = ceil($total / self::SEARCH_PER_PAGE); $params['publications'] = $publications; $return = array(); foreach ($publications as $item) { $return[] = ['id' => $item->getId(), 'name' => $item->getTitle()]; } return $this->render('EvrikaMainBundle:Abbreviation:ajax.json.twig', array('data' => $return)); }
function sphinx_search($query, $offset = 0, $limit = 30) { require_once 'lib/sphinxapi.php'; $sphinxClient = new SphinxClient(); $sphinxClient->SetServer('localhost', 9312); $sphinxClient->SetConnectTimeout(1); $sphinxClient->SetFieldWeights(array('title' => 70, 'content' => 30, 'feed_title' => 20)); $sphinxClient->SetMatchMode(SPH_MATCH_EXTENDED2); $sphinxClient->SetRankingMode(SPH_RANK_PROXIMITY_BM25); $sphinxClient->SetLimits($offset, $limit, 1000); $sphinxClient->SetArrayResult(false); $sphinxClient->SetFilter('owner_uid', array($_SESSION['uid'])); $result = $sphinxClient->Query($query, SPHINX_INDEX); $ids = array(); if (is_array($result['matches'])) { foreach (array_keys($result['matches']) as $int_id) { $ref_id = $result['matches'][$int_id]['attrs']['ref_id']; array_push($ids, $ref_id); } } return $ids; }
/** * Отправляет подготовленный запрос на сфинкс, и преобразует ответ в нужный вид. * * @param string $query поисковый запрос (в оригинальном виде) * @param int $storeId ИД текущего магазина * @param string $indexCode Код индекса по которому нужно провести поиск (mage_catalog_product ...) * @param string $primaryKey Primary Key индекса (entity_id, category_id, post_id ...) * @param array $attributes Масив атрибутов с весами * @param int $offset Страница * * @return array масив ИД елементов, где ИД - ключ, релевантность значение */ protected function _query($query, $storeId, $index, $offset = 1) { $uid = Mage::helper('mstcore/debug')->start(); $indexCode = $index->getCode(); $primaryKey = $index->getPrimaryKey(); $attributes = $index->getAttributes(); $client = new SphinxClient(); $client->setMaxQueryTime(5000); //5 seconds $client->setLimits(($offset - 1) * self::PAGE_SIZE, self::PAGE_SIZE, $this->_config->getResultLimit()); $client->setSortMode(SPH_SORT_RELEVANCE); $client->setMatchMode(SPH_MATCH_EXTENDED); $client->setServer($this->_spxHost, $this->_spxPort); $client->SetFieldWeights($attributes); if ($storeId) { $client->SetFilter('store_id', $storeId); } $sphinxQuery = $this->_buildQuery($query, $storeId); if (!$sphinxQuery) { return array(); } $sphinxQuery = '@(' . implode(',', $index->getSearchableAttributes()) . ')' . $sphinxQuery; $sphinxResult = $client->query($sphinxQuery, $indexCode); if ($sphinxResult === false) { Mage::throwException($client->GetLastError() . "\nQuery: " . $query); } elseif ($sphinxResult['total'] > 0) { $entityIds = array(); foreach ($sphinxResult['matches'] as $data) { $entityIds[$data['attrs'][strtolower($primaryKey)]] = $data['weight']; } if ($sphinxResult['total'] > $offset * self::PAGE_SIZE && $offset * self::PAGE_SIZE < $this->_config->getResultLimit()) { $newIds = $this->_query($query, $storeId, $index, $offset + 1); foreach ($newIds as $key => $value) { $entityIds[$key] = $value; } } } else { $entityIds = array(); } $entityIds = $this->_normalize($entityIds); Mage::helper('mstcore/debug')->end($uid, $entityIds); return $entityIds; }
/** * @return SphinxClient: ready to run or false if term is empty */ function prepareSphinxClient( &$term ) { global $wgSphinxSearch_sortmode, $wgSphinxSearch_sortby, $wgSphinxSearch_host, $wgSphinxSearch_port, $wgSphinxSearch_index_weights, $wgSphinxSearch_mode, $wgSphinxSearch_maxmatches, $wgSphinxSearch_cutoff, $wgSphinxSearch_weights; // don't do anything for blank searches if ( trim( $term ) === '' ) { return false; } wfRunHooks( 'SphinxSearchBeforeResults', array( &$term, &$this->offset, &$this->namespaces, &$this->categories, &$this->exc_categories ) ); $cl = new SphinxClient(); $cl->SetServer( $wgSphinxSearch_host, $wgSphinxSearch_port ); if ( $wgSphinxSearch_weights && count( $wgSphinxSearch_weights ) ) { $cl->SetFieldWeights( $wgSphinxSearch_weights ); } if ( is_array( $wgSphinxSearch_index_weights ) ) { $cl->SetIndexWeights( $wgSphinxSearch_index_weights ); } if ( $wgSphinxSearch_mode ) { $cl->SetMatchMode( $wgSphinxSearch_mode ); } if ( $this->namespaces && count( $this->namespaces ) ) { $cl->SetFilter( 'page_namespace', $this->namespaces ); } if( !$this->showRedirects ) { $cl->SetFilter( 'page_is_redirect', array( 0 ) ); } if ( $this->categories && count( $this->categories ) ) { $cl->SetFilter( 'category', $this->categories ); wfDebug( "SphinxSearch included categories: " . join( ', ', $this->categories ) . "\n" ); } if ( $this->exc_categories && count( $this->exc_categories ) ) { $cl->SetFilter( 'category', $this->exc_categories, true ); wfDebug( "SphinxSearch excluded categories: " . join( ', ', $this->exc_categories ) . "\n" ); } $cl->SetSortMode( $wgSphinxSearch_sortmode, $wgSphinxSearch_sortby ); $cl->SetLimits( $this->offset, $this->limit, $wgSphinxSearch_maxmatches, $wgSphinxSearch_cutoff ); wfRunHooks( 'SphinxSearchBeforeQuery', array( &$term, &$cl ) ); return $cl; }
fwrite($file, $client->_reqs[$client->AddQuery("test ")]); fclose($file); $client->SetWeights(array()); // anchor $client->SetGeoAnchor("latitude", "longitude", 10.0, 95.0); $file = fopen("spec/fixtures/data/anchor.bin", "w"); fwrite($file, $client->_reqs[$client->AddQuery("test ")]); fclose($file); $client->ResetFilters(); // rank_mode $client->SetRankingMode(SPH_RANK_WORDCOUNT); $file = fopen("spec/fixtures/data/rank_mode.bin", "w"); fwrite($file, $client->_reqs[$client->AddQuery("test ")]); fclose($file); $client->SetRankingMode(SPH_RANK_PROXIMITY_BM25); // index_weights $client->SetIndexWeights(array("people" => 101)); $file = fopen("spec/fixtures/data/index_weights.bin", "w"); fwrite($file, $client->_reqs[$client->AddQuery("test ")]); fclose($file); $client->SetIndexWeights(array()); // index_weights $client->SetFieldWeights(array("city" => 101)); $file = fopen("spec/fixtures/data/field_weights.bin", "w"); fwrite($file, $client->_reqs[$client->AddQuery("test ")]); fclose($file); $client->SetFieldWeights(array()); // update_simple $file = fopen("spec/fixtures/data/update_simple.bin", "w"); fwrite($file, $client->UpdateAttributes("people", array("birthday"), array(1 => array(191163600)))); fclose($file);
/** * This has it's own custom search. * * @param mixed[] $search_params * @param mixed[] $search_words * @param string[] $excluded_words * @param int[] $participants * @param string[] $search_results */ public function searchQuery($search_params, $search_words, $excluded_words, &$participants, &$search_results) { global $user_info, $context, $modSettings; // Only request the results if they haven't been cached yet. if (($cached_results = cache_get_data('search_results_' . md5($user_info['query_see_board'] . '_' . $context['params']))) === null) { // The API communicating with the search daemon. require_once SOURCEDIR . '/sphinxapi.php'; // Create an instance of the sphinx client and set a few options. $mySphinx = new SphinxClient(); $mySphinx->SetServer($modSettings['sphinx_searchd_server'], (int) $modSettings['sphinx_searchd_port']); $mySphinx->SetLimits(0, (int) $modSettings['sphinx_max_results'], (int) $modSettings['sphinx_max_results']); // Put together a sort string; besides the main column sort (relevance, id_topic, or num_replies), $search_params['sort_dir'] = strtoupper($search_params['sort_dir']); $sphinx_sort = $search_params['sort'] === 'id_msg' ? 'id_topic' : $search_params['sort']; // Add secondary sorting based on relevance value (if not the main sort method) and age $sphinx_sort .= ' ' . $search_params['sort_dir'] . ($search_params['sort'] === 'relevance' ? '' : ', relevance DESC') . ', poster_time DESC'; // Include the engines weight values in the group sort $sphinx_sort = str_replace('relevance ', '@weight ' . $search_params['sort_dir'] . ', relevance ', $sphinx_sort); // Grouping by topic id makes it return only one result per topic, so don't set that for in-topic searches if (empty($search_params['topic'])) { $mySphinx->SetGroupBy('id_topic', SPH_GROUPBY_ATTR, $sphinx_sort); } // Set up the sort expresssion $mySphinx->SetSortMode(SPH_SORT_EXPR, '(@weight + (relevance / 1000))'); // Update the field weights for subject vs body $mySphinx->SetFieldWeights(array('subject' => !empty($modSettings['search_weight_subject']) ? $modSettings['search_weight_subject'] * 200 : 1000, 'body' => 1000)); // Set the limits based on the search parameters. if (!empty($search_params['min_msg_id']) || !empty($search_params['max_msg_id'])) { $mySphinx->SetIDRange($search_params['min_msg_id'], empty($search_params['max_msg_id']) ? (int) $modSettings['maxMsgID'] : $search_params['max_msg_id']); } if (!empty($search_params['topic'])) { $mySphinx->SetFilter('id_topic', array((int) $search_params['topic'])); } if (!empty($search_params['brd'])) { $mySphinx->SetFilter('id_board', $search_params['brd']); } if (!empty($search_params['memberlist'])) { $mySphinx->SetFilter('id_member', $search_params['memberlist']); } // Construct the (binary mode & |) query while accounting for excluded words $orResults = array(); $inc_words = array(); foreach ($search_words as $orIndex => $words) { $inc_words = array_merge($inc_words, $words['indexed_words']); $andResult = ''; foreach ($words['indexed_words'] as $sphinxWord) { $andResult .= (in_array($sphinxWord, $excluded_words) ? '-' : '') . $this->_cleanWordSphinx($sphinxWord, $mySphinx) . ' & '; } $orResults[] = substr($andResult, 0, -3); } // If no search terms are left after comparing against excluded words (i.e. "test -test" or "test last -test -last"), // sending that to Sphinx would result in a fatal error if (!count(array_diff($inc_words, $excluded_words))) { // Instead, fail gracefully (return "no results") return 0; } $query = count($orResults) === 1 ? $orResults[0] : '(' . implode(') | (', $orResults) . ')'; // Subject only searches need to be specified. if ($search_params['subject_only']) { $query = '@(subject) ' . $query; } // Choose an appropriate matching mode $mode = SPH_MATCH_ALL; // Over two words and searching for any (since we build a binary string, this will never get set) if (substr_count($query, ' ') > 1 && (!empty($search_params['searchtype']) && $search_params['searchtype'] == 2)) { $mode = SPH_MATCH_ANY; } // Binary search? if (preg_match('~[\\|\\(\\)\\^\\$\\?"\\/=-]~', $query)) { $mode = SPH_MATCH_EXTENDED; } // Set the matching mode $mySphinx->SetMatchMode($mode); // Execute the search query. $request = $mySphinx->Query($query, 'elkarte_index'); // Can a connection to the daemon be made? if ($request === false) { // Just log the error. if ($mySphinx->GetLastError()) { log_error($mySphinx->GetLastError()); } fatal_lang_error('error_no_search_daemon'); } // Get the relevant information from the search results. $cached_results = array('matches' => array(), 'num_results' => $request['total']); if (isset($request['matches'])) { foreach ($request['matches'] as $msgID => $match) { $cached_results['matches'][$msgID] = array('id' => $match['attrs']['id_topic'], 'relevance' => round($match['attrs']['@count'] + $match['attrs']['relevance'] / 10000, 1) . '%', 'num_matches' => empty($search_params['topic']) ? $match['attrs']['@count'] : 0, 'matches' => array()); } } // Store the search results in the cache. cache_put_data('search_results_' . md5($user_info['query_see_board'] . '_' . $context['params']), $cached_results, 600); } $participants = array(); foreach (array_slice(array_keys($cached_results['matches']), $_REQUEST['start'], $modSettings['search_results_per_page']) as $msgID) { $context['topics'][$msgID] = $cached_results['matches'][$msgID]; $participants[$cached_results['matches'][$msgID]['id']] = false; } // Sentences need to be broken up in words for proper highlighting. $search_results = array(); foreach ($search_words as $orIndex => $words) { $search_results = array_merge($search_results, $search_words[$orIndex]['subject_words']); } return $cached_results['num_results']; }
function search() { global $display; $catid = (int) Url::get('catid', 0); $total = (int) Url::get('total', 0); $page = (int) Url::get('page', 0); $tt = (int) Url::get('tt', 0); $keywords = Url::get('keywords'); require "./includes/sphinxapi.class.php"; EClassApi::getCats(); foreach (CGlobal::$allCategories as $value) { if ($value['parent_id'] == 0) { $cat_list[$value['id']] = $value['brief_name']; } } $category = $this->getCategory($keywords); foreach ($category as $row) { $row['brief_name'] = isset($cat_list[$row['level_1_category_id']]) && $cat_list[$row['level_1_category_id']] ? $cat_list[$row['level_1_category_id']] : "Khác"; $listCat[$row['level_1_category_id']] = array("level_1_category_id" => $row["level_1_category_id"], "brief_name" => $row['brief_name'], "count_ad" => $row['@count']); } $catActive = ''; $total_cat = 0; if ($listCat) { $catActive = $listCat[$catid]['brief_name']; $total_cat = count($listCat); } $i = 0; $allrecord = 0; $otherCat = ''; $cat_content = ""; foreach ($listCat as $cat) { $allrecord = $allrecord + $cat['count_ad']; } $display->add("cat_content", $cat_content); $display->add("CatActiveId", $catid); $display->add("catActive", $catActive); $display->add("listCat", $listCat); $display->add("allrecord", $allrecord); $display->add("total_cat", $total_cat); $pager = new Pager(); $limit = SEARCH_LIMIT; $pager->type = "search"; $pager->catid = $catid; $pager->total = $total; $pager->limit = $limit; $pager->page_param = 'page'; $pager->page = $page; $offset = $pager->get_offset(); $limit_from = $pager->limit_from(); $limit_to = $pager->limit_to(); //Sphinx search by Nova $q = $keywords; //$mode = SPH_MATCH_ALL; $mode = SPH_MATCH_EXTENDED2; //Init config $host = SPHINX_SERVER; $port = SPHINX_PORT; $index = 'enbac'; $filtervals = array(); //$ranker = SPH_RANK_PROXIMITY_BM25; $ranker = SPH_RANK_WORDCOUNT; $cl = new SphinxClient(); $cl->SetServer($host, $port); $cl->SetConnectTimeout(1); $cl->SetWeights(array(100, 1)); $cl->SetMatchMode($mode); $cl->SetFilter('level_1_category_id', array($catid)); $cl->SetFilter('status', array('1')); $cl->SetFieldWeights(array('user_name' => 10000, 'name' => 1000, 'description' => 1)); //$cl->SetSortMode( SPH_SORT_EXTENDED, 'up_time DESC' ); //$cl->SetSortMode( SPH_SORT_RELEVANCE);//Sort theo kq chính xác nhất //$cl->SetSortMode ( SPH_SORT_EXPR, "@weight + ( user_karma + ln(pageviews) )*0.1"); $cl->SetSortMode(SPH_SORT_EXPR, "@weight"); //Sort theo trọng số $cl->SetLimits($offset, $limit, 10000); $cl->SetRankingMode($ranker); $cl->SetArrayResult(true); $res = $cl->Query($q, $index); if ($res && isset($res["matches"])) { if (is_array($res["matches"])) { foreach ($res["matches"] as $results) { $list_item_id[] = $results['id']; } } $comma_separated = join(",", $list_item_id); } if ($total) { if ($limit_to > $total) { $limit_to = $total; } $comma_separated = join(",", $list_item_id); if ($comma_separated) { //$sql = "SELECT id,name,up_time,price,user_id,user_name, level_1_category_id,category_id,description,original_image_url, img_server FROM item WHERE id IN ($comma_separated) AND status=1 ORDER BY up_time DESC"; $sql = "SELECT id,name,up_time,price,user_id,user_name, level_1_category_id,category_id,description,original_image_url, img_server FROM item WHERE id IN ({$comma_separated}) AND status=1 ORDER BY find_in_set(id,'{$comma_separated}')"; $search_result = DB::query($sql); $pager->total = $total; $paging = $pager->page_link(); } } $item_array = array(); if ($search_result) { EClassApi::getCats(); $highlight = ''; if ($keywords) { $highlight = $str_search = str_replace(array('+', '/', '|', '-', '*'), "", $keywords); $highlight = EClassApi::trimSpace($highlight); $highlight = str_replace("'", '', $highlight); $highlight = str_replace("'", '', $highlight); $highlight = str_replace(""", '', $highlight); } $highlight1 = ''; if ($highlight) { $arr = explode(' ', $highlight); if ($arr) { $highlight = ""; foreach ($arr as $word) { $highlight = ($highlight ? $highlight . ', ' : '') . "'{$word}'"; $highlight1 = ($highlight1 ? $highlight1 . ',' : '') . $word; } } } while ($item = mysql_fetch_assoc($search_result)) { $item['profile_url'] = WEB_DIR . $item['user_name']; //$item['name'] = EClassApi::subString(strip_tags(EClassApi::filter_title($item['name'])), 0, 115, true); $item['name_hl'] = EClassApi::HighLightKeyword(strip_tags(EClassApi::filter_title($item['name'])), $highlight1); $item_time = TIME_NOW - $item['up_time']; //neu nho hon 1h thi tinh ra phut if ($item_time < 3600) { $item['item_time'] = floor($item_time / 60) . " phút trước đây"; } elseif ($item_time < 86400) { $item['item_time'] = floor($item_time / 3600) . " giờ trước đây"; } else { $item['item_time'] = date('\\n\\gà\\y j \\t\\há\\n\\g n', $item['up_time']); } //$item['description'] = String::display_sort_title(EClassApi::delDoubleSpace(EClassApi::trimSpace(strip_tags(EClassApi::post_db_parse_html($item['description'])))), 35); $item['description'] = EClassApi::HighLightKeyword(EClassApi::delDoubleSpace(EClassApi::trimSpace(strip_tags(EClassApi::post_db_parse_html(preg_replace('/\\[[0-9]{1,3}\\]/', '', $item['description']))))), $highlight1, 35, "background:yellow;font-size:14px;font-weight:bold;color:blue;"); $ebname = EClassApi::safe_title($item['name']); $ebname_tmp = substr(EClassApi::safe_title($item['name']), 0, 20); if (isset(CGlobal::$allCategories[$item['category_id']])) { $item['item_url'] = WEB_DIR . ECRewrite::formatUrl('?page=item_detail&id=' . $item['id'] . '&ebname=' . $ebname . '&nice_name=' . CGlobal::$allCategories[$item['category_id']]['nice_name']); $item['item_url_tmp'] = WEB_ROOT . CGlobal::$allCategories[$item['category_id']]['nice_name'] . '/p' . $item['id'] . '/' . $ebname_tmp . '...'; } else { $item['item_url'] = WEB_DIR . ECRewrite::formatUrl('?page=item_detail&id=' . $item['id'] . '&ebname=' . $ebname); $item['item_url_tmp'] = WEB_ROOT . 'p' . $item['id'] . '/' . $ebname_tmp . '...'; } if ($item['original_image_url']) { $item['original_image_url'] = EClassApi::getImageThumb($item['original_image_url'], 110, 0, 1, $item['img_server']); } $item['price'] = number_format($item['price'], 0, ',', '.'); $item_array[] = $item; } } $display->add('total_item_cat', $total); $display->add('name_item_cat', $catActive); $display->add('paging', $paging); $display->add('keywords', $keywords); $display->add('items', $item_array); $display->output('sphinx_search_ajax', false, 'sphinx_search'); }
public function fromSphinx($data) { $this->data = $data; if (isset($this->data['redword']) && !empty($this->data['redword'])) { $this->data['split'] = $this->data['redword']; } else { //分词 $this->data['split'] = $this->data['wd']; $splitWd = \Xz\Func\Common\Tools::curlGetContentMs($this->di['config']->base->split . '/wd/' . urlencode($this->data['wd']), 50); if ($splitWd) { $this->data['split'] = $splitWd; } } $this->data['split'] = $this->getSplitWd($this->data['split']); $sphinxConfig = $this->di["config"]["prosearchd"]; $sphinx = new \SphinxClient(); $sphinx->SetServer($sphinxConfig['host'], intval($sphinxConfig['port'])); //$sphinx->SetMatchMode(SPH_MATCH_EXTENDED2); $indexTable = "product_distri"; //TODO 索引范围 if (!isset($this->data['cateid'])) { if (isset($this->data['cate3'])) { $this->data['cateid'] = $this->data['cate3']; } } //逻辑判断必须加>0 if (isset($this->data['cateid']) && $this->data['cateid'] > 0) { $cateinfo = \Xz\Lib\Cate::getCateInfo(array($this->data['cateid']), array('nav')); if (!empty($cateinfo)) { $this->data['cate1'] = $cateinfo[$this->data['cateid']]['nav'][0]['cateid']; $indexTable = "product_distri" . '_' . $this->data['cate1']; } //$indexTable = "product_distri"; } $gcdweight = "weight()+IF(id>900000000, tradenum*100, 0)+inquirynum*20+star*2+basescore*5+creditscore+IF(is_op=1, all_uv*10+all_pv, 0)+IF(id>900000000, weight()*0.1, 0) as gcpdweight"; $sphinx->SetSelect("id, cid, brand, feature, province, city, {$gcdweight}"); if (!empty($this->data['cateid']) && intval($this->data['cateid']) > 0) { $sphinx->SetFilter('cate3', array(intval($this->data['cateid'])), false); } if (!empty($this->data['brand']) && intval($this->data['brand']) > 0) { $sphinx->SetFilter('brand', array(intval($this->data['brand'])), false); } if (!empty($this->data['province']) && intval($this->data['province']) > 0) { $sphinx->SetFilter('province', array(intval($this->data['province'])), false); } if (!empty($this->data['city']) && intval($this->data['city']) > 0) { $sphinx->SetFilter('city', array(intval($this->data['city'])), false); } if (!empty($this->data['iscertify']) && intval($this->data['iscertify']) > 0) { $sphinx->SetFilter('is_gccertify', array(intval($this->data['iscertify'])), false); } if (!empty($this->data['isprice']) && intval($this->data['isprice']) > 0) { $sphinx->SetFilterRange('price', 1, 9999999, false); } if (!empty($this->data['feature'])) { $featureArr = explode('_', $this->data['feature']); foreach ($featureArr as $value) { $sphinx->SetFilter('feature', array(intval($value)), false); } } $sphinx->SetFieldWeights(array('proname' => 300, 'comname' => 10, 'prokey' => 10, 'brandname' => 300, 'cate1str' => 50, 'cate2str' => 50, 'cate3str' => 60, 'citystr' => 60, 'provincstr' => 60)); if (!empty($this->data['sort'])) { switch ($this->data['sort']) { case 1: $sphinx->SetSortMode(SPH_SORT_EXTENDED, 'tradenum DESC'); break; case 2: $sphinx->SetSortMode(SPH_SORT_EXTENDED, 'visitnum DESC'); //访问量/热度 break; case 3: $sphinx->SetSortMode(SPH_SORT_EXTENDED, 'price DESC'); break; case 4: $sphinx->SetSortMode(SPH_SORT_EXTENDED, 'price ASC'); break; case 6: $sphinx->SetSortMode(SPH_SORT_EXTENDED, 'integral DESC'); break; default: $sphinx->SetSortMode(SPH_SORT_EXTENDED, 'gcpdweight DESC'); break; } } else { $sphinx->SetSortMode(SPH_SORT_EXTENDED, 'gcpdweight DESC'); } if (isset($this->data['baping']) && $this->data['baping'] == 1) { $sphinx->SetLimits(0, 1000, 1000); } else { $sphinx->SetLimits(0, 200, 200); } $sphinx->AddQuery($this->data['split'], $indexTable); $sphinx->ResetGroupBy(); $sphinx->SetGroupBy('feature', SPH_GROUPBY_ATTR, "@count desc"); $sphinx->SetLimits(0, 20, 20); $sphinx->AddQuery($this->data['split'], $indexTable); $sphinx->ResetGroupBy(); $sphinx->SetLimits(0, 20, 20); $sphinx->SetGroupBy('brand', SPH_GROUPBY_ATTR, "@count desc"); $sphinx->AddQuery($this->data['split'], $indexTable); if (!empty($this->data['province'])) { //市 $sphinx->ResetGroupBy(); $sphinx->SetLimits(0, 20, 20); $sphinx->SetGroupBy('city', SPH_GROUPBY_ATTR, "@count desc"); $sphinx->AddQuery($this->data['split'], $indexTable); } else { //省 $sphinx->ResetGroupBy(); $sphinx->SetLimits(0, 20, 20); $sphinx->SetGroupBy('province', SPH_GROUPBY_ATTR, "@count desc"); $sphinx->AddQuery($this->data['split'], $indexTable); } $batchResult = $sphinx->RunQueries(); $error = $sphinx->getLastError(); if ($error) { $result['data'] = array(); $result['property'] = '[]'; $result['brand'] = '[]'; $result['city'] = '[]'; $result['province'] = '[]'; $result['total_found'] = 0; $result['time'] = 0; $result['split'] = $this->data['split']; return $result['data']; } $result = array(); if (is_array($batchResult) && count($batchResult) > 0) { $result['data'] = $batchResult[0]; //$result['cate3'] = isset($batchResult[1]) ? $batchResult[1] : array(); $result['property'] = isset($batchResult[1]) ? $batchResult[1] : array(); $result['brand'] = isset($batchResult[2]) ? $batchResult[2] : array(); if (!empty($this->data['province'])) { $result['city'] = isset($batchResult[3]) ? $batchResult[3] : array(); } else { $result['province'] = isset($batchResult[3]) ? $batchResult[3] : array(); } } $resData = array(); if (isset($result['data']['matches'])) { foreach ($result['data']['matches'] as $k => $v) { $resData[] = array($k, $v['attrs']['cid']); } } $result['total_found'] = $result['data']['total_found']; $result['time'] = $result['data']['time']; $result['split'] = $this->data['split']; $result['data'] = $resData; //防霸屏 $result['data'] = $this->sortData($result['data']); if (!empty($result['province'])) { $province = $this->fomatSphinxData($result['province']); $result['province'] = json_encode($province); } else { $result['province'] = '[]'; } if (!empty($result['city'])) { $city = $this->fomatSphinxData($result['city']); $result['city'] = json_encode($city); } else { $result['city'] = '[]'; } if (!empty($result['brand'])) { $brand = $this->fomatSphinxData($result['brand']); $result['brand'] = json_encode($brand); } else { $result['brand'] = '[]'; } if (!empty($result['property'])) { $property = $this->fomatSphinxData($result['property']); $result['property'] = json_encode($property); } else { $result['property'] = '[]'; } return $result; }