Я только начинаю работать со Сфинксом. На данный момент я успешно установил его, проиндексировал таблицу с именем profiles
в моей базе данных MySQL и могу получить правильные результаты с помощью PHP API. Я использую CodeIgniter, поэтому я обернул PHP API по умолчанию как библиотеку CodeIgniter.
Во всяком случае, вот как выглядит мой код:
$query = $_GET['q'];
$this->load->library('sphinxclient');
$this->sphinxclient->setMatchMode(SPH_MATCH_ANY);
$result = $this->sphinxclient->query($query);
$to_fetch = array();
foreach($result['matches'] as $key => $match) {
array_push($to_fetch, $key);
}
Массив $to_fetch
содержит идентификаторы соответствующих строк таблицы. Теперь я могу использовать типичный запрос MySQL, чтобы вывести всех релевантных пользователей на страницу поиска следующим образом:
$query = 'SELECT * FROM profiles WHERE id IN('. join(',', $to_fetch) . ')';
Мой вопрос:
правильный ли это способ? или есть ли по умолчанию «способ Sphinx сделать это», который был бы лучше для производительности.
во-вторых, все, что я получаю в данный момент, это идентификатор совпадающих строк таблицы. Я также хочу, чтобы часть текста в столбце соответствовала. Например, если кто-то ищет ключевое слово собака
, а пользователь в таблице profiles
имеет в столбце about
следующий текст:
Мне нравятся собаки. . Я также люблю мороженое.
Я бы хотел, чтобы Сфинкс вернулся:
I like <strong>dogs</strong>. I also like ice cream.
Как я могу это сделать? Я пытался поиграть с функцией buildExcerpts()
, но не смог заставить ее работать.
Вот как теперь я получаю выдержки:
// get matched user ids
$to_fetch = array();
foreach($result['matches'] as $key => $match) {
array_push($to_fetch, $key);
}
// get user details of matched ids
$members = $this->search_m->get_users_by_id($to_fetch);
// build excerpts
$excerpts = array();
foreach($members as $member) {
$fields = array(
$member['about'],
$member['likes'],
$member['dislikes'],
$member['occupation']
);
$options = array(
'before_match' => '<strong class="match">',
'after_match' => '</strong>',
'chunk_separator' => ' ... ',
'limit' => 60,
'around' => 3,
);
$excerpt_result = $this->sphinxclient->BuildExcerpts($fields, 'profiles', $query, $options);
$excerpts[$member['user_id']] = $excerpt_result;
}
$excerpts_to_return = array();
foreach($excerpts as $key => $excerpt) {
foreach($excerpt as $v) {
if(strpos($v, '<strong class="match">') !== false) {
$excerpts_to_return[$key] = $v;
}
}
}
Как видите, я ищу каждый запрос по 4 различным столбцам mysql:
about
likes
dislikes
occupation
Из-за этого я не знаю, какой из 4 столбцов содержит совпадающее ключевое слово. Это может быть любой из них или даже несколько. Поэтому у меня нет другого выбора, кроме как запустить содержимое всех 4 столбцов через функцию BuildExcerpts()
.
Даже тогда я не знаю, какой из них вернул BuildExcerpts()
с тегами . Поэтому я запускаю
stpos
проверку всех значений, возвращаемых BuildExcerpts()
, чтобы, наконец, получить правильную выдержку и сопоставить ее с пользователем, чьему профилю она принадлежит.
Вы видите лучший способ, чем этот, учитывая мою ситуацию, когда мне нужно сопоставить содержимое 4 разных столбцов?