Я пытаюсь выполнить поиск нескольких таблиц MySQL с различными полями, используя Sphinx, и объединить все результаты в один набор, основанный на релевантности.
Я сконфигурировал Sphinx с индексом для каждой таблицы и успешно совмещаю результаты, одновременно просматривая все индексы.
Когда я запрашиваю использование SEARCH
через оболочку, я получаю всю информацию о результатах обратно, как ожидалось. Однако, когда я использую PHP API, результат возвращается только с идентификаторами строк и, следовательно, никак не может определить, из какой таблицы он пришел.
Есть ли способ заставить PHP API рассказать мне, какая таблица / индекс он пришел, чтобы я мог войти и запросить фактические данные?
Альтернатива, которую я рассматриваю, заключается в попытке обработать вывод из сценария оболочки, но это кажется беспорядочным.
Вот PHP: $ search = $ _GET ['query']; // Информация о соединении $ sphinxClient = new SphinxClient (); $ sphinxClient-> SetServer ('localhost', 9312); $ SphinxClient-> SetMaxQueryTime (5000);
//Sphinx Result Configuration $sphinxClient->SetMatchMode(SPH_MATCH_ANY); $sphinxClient->SetRankingMode( SPH_RANK_PROXIMITY_BM25 ); $sphinxClient->SetLimits(0, 20); // Give me back the results as an array $sphinxClient->SetArrayResult(true); $searchResults = $sphinxClient->Query( $search, 'user model' );
Скрипт оболочки просто:
./search SEARCHTERM
где SEARCHTERM – это поиск
который выводит что-то похожее:
Sphinx 2.0.3-release (r3043) Copyright (c) 2001-2011, Andrew Aksyonoff Авторское право (c) 2008-2011, Sphinx Technologies Inc (http://sphinxsearch.com)
используя файл конфигурации '/usr/local/sphinx/etc/sphinx.conf' … index 'user': query 'NEWTON': возвращено 10 совпадений из 10 всего за 0.000 секунд
отображение совпадений: 1. document = 1, weight = 2629, time = Thu Jan 1 00:33:32 1970 id = 1 first_name = Joe last_name = Shmo company = Acme
Выход API PHP в формате JSON: {"error": "", "warning": "", "status": "good", "fields": ["name", "code_name", "code", "description »,« рейтинг »,« углы »,« опубликованные »,« ключевые слова »,« referenced_num »,« одобренные »,« used_num »,« avg_runtime »,« примеры »,« editor »,« publish_time »],« attrs », : {"time": 2}, "matches": [{"id": 1, "weight": "1", "attrs": {"time": 2012}}], "total": "1" , "total_found": "1", "time": "0.000", "words": {"posuere": {"docs": "1", "hits": "2"}}}
Это нормально, что Sphinx возвращает идентификаторы объекта (строки). Проблема в вашей модели. Если вы не можете определить по id, какой именно объект, ваша модель неверна. Возможные варианты:
Я абсолютно уверен, что при поиске по API вы не только получаете идентификаторы совпадающих документов, но и все другие значения int найденного документа.
Поэтому вы можете попробовать добавить в свой источник что-то вроде
SELECT id, "1" as type FROM table1 sql_attr_uint = type
и поле type
теперь сообщает вам, в какой таблице находится идентификатор
Обратите внимание, однако, что есть несколько проблем с одновременным поиском нескольких индексов разных таблиц.
Вам нужно убедиться, что идентификатор не отображается больше, чем один раз в вашем результирующем наборе (обычно предлагаемым решением было бы поместить идентификатор на 1000000 или каким-то другим способом, что лично я считаю ужасным)
Результаты содержат только столбцы от первого найденного индекса. Вы должны убедиться, что все ваши источники возвращают одни и те же столбцы.
Лично каждый раз, когда я думал о поиске нескольких индексов сразу, я в конечном итоге искал каждый отдельно и представлял результаты как таковые.
Обновление: добавлен sql_attr_uint
если таблицы имеют одинаковую структуру, вы можете использовать объединение с вашими sql-запросами
SELECT * FROM table1 WHERE id IN (ids,from,sphinx) UNION SELECT * FROM table2 WHERE id IN (ids,from,sphinx) ... UNION SELECT * FROM tableN WHERE id IN (ids,from,sphinx)
будьте осторожны, что это интенсивный процессор