/** * Reset settings sphinx */ public function resetClient() { $this->_client->resetFilters(); $this->_client->resetGroupBy(); $this->_client->setArrayResult(false); //DEPRECATED: Do not call this method or, even better, use SphinxQL instead of an API //$this->_client->setMatchMode(SPH_MATCH_EXTENDED2); $this->_client->setLimits(0, 20, 1000, 0); $this->_client->setFieldWeights(array()); $this->_client->setSortMode(SPH_SORT_RELEVANCE, ''); $this->_client->_error = ''; $this->_client->_warning = ''; }
/** * Отправляет подготовленный запрос на сфинкс, и преобразует ответ в нужный вид. * * @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; }
/** * @param \SphinxClient $sphinx */ public function bindToSphinx(\SphinxClient $sphinx) { $sphinx->setSortMode($this->getMode(), $this->getSortBy()); }
/** * @brief reset search criteria to default * @details reset conditions and set default search options */ public function resetCriteria() { if (is_object($this->criteria)) { $this->lastCriteria = clone $this->criteria; } else { $this->lastCriteria = new stdClass(); } $this->criteria = new stdClass(); $this->criteria->query = ''; $this->client->resetFilters(); $this->client->resetGroupBy(); $this->client->setArrayResult(false); $this->client->setMatchMode($this->matchMode); // $this->client->setRankingMode($this->rankMode); $this->client->setSortMode(SPH_SORT_RELEVANCE, '@relevance DESC'); $this->client->setLimits(0, 1000000, 10000); if (!empty($this->fieldWeights)) { $this->client->setFieldWeights($this->fieldWeights); } }
/** * Фильтр по аббривиатурам * * @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)); }
public function setSortMode($mode, $str) { $this->sphinx->setSortMode($mode, $str); }
$T->load(file_get_contents('tpl/index.tpl')); $tpl_values = array(); $tpl_values['page'] = $page; if ($query || $extsearch) { $tpl_values['query'] = htmlspecialchars($query); $tpl_values['extsearch'] = $extsearch; $tpl_values['nodirs'] = $nodirs; $categories = Searcher::getCategories($category, true); $tpl_values['categories'] = $categories; $tpl_values['days'] = $days; $tpl_values['minsize'] = $minsize; if ($query) { $searcher = new SphinxClient(); $searcher->setServer("localhost", 3312); $searcher->setMatchMode(SPH_MATCH_ALL); $searcher->setSortMode(SPH_SORT_RELEVANCE); $searcher->setMaxQueryTime(3000); $min = ($page - 1) * RPP; $max = $min + RPP; //max+1 $out_array = array(); //TTHS $prev_instanses_count = 0; $start = max(0, $min - $prev_instanses_count); $len = min(RPP, max(1, $max - $prev_instanses_count)); $searcher->setLimits($start, $len); $tths_result = $searcher->query($query, "dc_tths dc_tths_delta"); $total_tths = $tths_result['total']; if ($total_tths && is_array($tths_result['matches']) && count($out_array) < RPP) { $tths = Searcher::getTTHs(array_keys($tths_result['matches'])); $out_array = array_merge($out_array, $tths);
/** * Runs a search against sphinx * * @param array $args * @return array Sphinx result set */ public function search_posts($args) { $options = $this->get_options(); $defaults = array('search_using' => 'any', 'sort' => 'match', 'paged' => 1, 'posts_per_page' => 0, 'showposts' => 0); $args = wp_parse_args($args, $defaults); $sphinx = new SphinxClient(); $sphinx->setServer($options['server'], $options['port']); $search = $args['s']; switch ($args['search_using']) { case 'all': $sphinx->setMatchMode(SPH_MATCH_ALL); break; case 'exact': $sphinx->setMatchMode(SPH_MATCH_PHRASE); break; default: $sphinx->setMatchMode(SPH_MATCH_ANY); } switch ($args['sort']) { case 'date': $sphinx->setSortMode(SPH_SORT_ATTR_DESC, 'date_added'); break; case 'title': $sphinx->setSortMode(SPH_SORT_ATTR_ASC, 'title'); break; default: $sphinx->setSortMode(SPH_SORT_RELEVANCE); } $page = isset($args['paged']) && intval($args['paged']) > 0 ? intval($args['paged']) : 1; $per_page = max(array($args['posts_per_page'], $args['showposts'])); if ($per_page < 1) { $per_page = get_option('posts_per_page'); } $sphinx->setLimits(($page - 1) * $per_page, $per_page); $sphinx->setMaxQueryTime(intval($options['timeout'])); $result = $sphinx->query($search, $options['index']); $this->last_error = $sphinx->getLastError(); $this->last_warning = $sphinx->getLastWarning(); return $result; }
8、权重排序 9、排除一些影响元素 10、添加新词 11、实时索引 12、删除数据 13、sphinx分页 */ header("content-type:text/html;charset=utf-8"); include './sphinxapi.php'; $key = $_GET['keyword']; $sp = new SphinxClient(); $sp->setServer('localhost', 9312); //改变关键字匹配模式 SPH_MATCH_EXTENDED2支持权重排序 $sp->setMatchMode(SPH_MATCH_EXTENDED2); //改变搜索排序模式 sphinx自带id weight 前面加@ 和表关联的字段不用加,优先级前后关系 $sp->setSortMode(SPH_SORT_EXTENDED, 'weight desc @weight desc'); //筛选指定字段的指定值保留,其他不显示 $sp->setFilter('status', array(1)); //分页 $sp->setLimits(4, 4); //搜索根据相关索引 $result = $sp->query($key, 'ind_post ind_post_new'); echo "<pre>"; print_r($result['matches']); $ids = implode(",", array_keys($result['matches'])); mysql_connect("localhost", "root", "123"); mysql_select_db("test"); mysql_set_charset("utf8"); echo $sql = "select * from post where id in (" . $ids . ") order by field(id," . $ids . ")"; $res = mysql_query($sql); $posts = array();
function getRecipes($advanced) { include __ROOT__ . "sphinx/api.php"; $cl = new SphinxClient(); $cl->SetServer("localhost", 9312); $l = isset($advanced['limit']) ? $advanced['limit'] : 10; $limit = isset($advanced['page']) ? (int) $advanced['page'] * $l : 0; $cl->setLimits($limit, $l + 1); $lang_id = 0; if ($advanced['favorites'] == 1 && VF::app()->user->isAuth()) { $ids_a = array(); $ids = VF::app()->database->sql("SELECT recipe_id FROM recipes_likes WHERE user_id = " . VF::app()->user->getId())->queryAll(); foreach ($ids as $i) { $ids_a[] = $i['recipe_id']; } if (empty($ids_a)) { return array(); } $cl->setFilter('id_attr', $ids_a); } else { if (isset($advanced['lang_id'])) { $lang_id = $advanced['lang_id']; } else { $lang_id = VF::app()->lang_id; } } if ($advanced['country_id'] > 0) { $cl->setFilter('country_id', array($advanced['country_id'])); } if ($advanced['category_id'] > 0) { $cl->setFilter('category_id', array($advanced['category_id'])); $lang_id = 0; } if ($lang_id > 0) { $cl->setFilter('lang_id', array($lang_id)); } if (!empty($advanced['ingredient_id'])) { $ids_a = array(); $a = explode(",", $advanced['ingredient_id']); if (count($a) > 1) { $sql = "SELECT recipe_id, count(Distinct ingredient_id)\n FROM recipes2ingredients\n WHERE ingredient_ID in (" . $advanced['ingredient_id'] . ")\n GROUP BY recipe_id\n HAVING count(Distinct ingredient_id) = " . count($a); } else { $sql = "SELECT recipe_id FROM recipes2ingredients WHERE ingredient_id = " . $advanced['ingredient_id'] . " LIMIT 300"; } $ids = VF::app()->database->sql($sql)->queryAll(); foreach ($ids as $i) { $ids_a[] = $i['recipe_id']; } $cl->setFilter('id_attr', $ids_a); } if (!empty($advanced['query'])) { $results = $cl->Query($advanced['query']); // поисковый запрос } else { $cl->SetMatchMode(SPH_MATCH_FULLSCAN); // ищем хотя бы 1 слово из поисковой фразы $cl->setSortMode(SPH_SORT_ATTR_DESC, 'date_created'); $results = $cl->Query('*'); // поисковый запрос } $this->total_found = $results['total_found']; $arr = array(); if (!empty($results['matches'])) { foreach ($results['matches'] as $r) { $r['attrs']['id'] = $r['attrs']['id_attr']; $arr[] = $r['attrs']; } } return $arr; }
// check for post data if (isset($_POST["keyWord"]) || isset($_POST["location"]) || isset($_POST["special"])) { $offset = 0; $limit = 10; $max_matches = 100; require_once 'C:\\Sphinx\\api\\sphinxapi.php'; $s = new SphinxClient(); $s->setServer("127.0.0.1", 9312); $s->setMatchMode(SPH_MATCH_EXTENDED2); if (isset($_POST['offset'])) { $offset = $_POST['offset']; } //$sortMode='ratepoint'; if (isset($_POST["sortMode"])) { $sortMode = $_POST["sortMode"]; $s->setSortMode(SPH_SORT_ATTR_DESC, $sortMode); } $s->SetLimits((int) $offset, (int) $limit, (int) $limit > $max_matches ? (int) $limit : (int) $max_matches); if (isset($_POST["keyWord"]) && isset($_POST["location"]) && isset($_POST["special"])) { $keyWord = $_POST['keyWord']; $location = $_POST['location']; $special = $_POST['special']; $result = $s->Query("@(JobName,Company) {$keyWord} @location {$location} @(Requirement,Tags) {$special}"); } else { if (isset($_POST["keyWord"]) && isset($_POST["location"])) { $keyWord = $_POST['keyWord']; $location = $_POST['location']; $result = $s->Query("@(JobName,Company) {$keyWord} @location {$location}"); } else { if (isset($_POST["keyWord"]) && isset($_POST["special"])) { $keyWord = $_POST['keyWord'];