Начинается с фильтра запроса для elasticsearch с использованием elastica

У меня есть реализация поиска elasticsearch, работающая для веб-приложения, но я застрял на последней детали. Я хочу иметь возможность фильтровать определенные поля по алфавиту. Поэтому, если я запрошу «d», он должен вернуть все, что начинается с «d» для этого поля. На данный момент это то, что у меня есть:

$elasticaQueryString = new Elastica_Query_QueryString();
$elasticaQueryString->setDefaultField('Name');
$elasticaQueryString->setQuery('d'.'*');

Это работает для полей, в которых есть только одна работа, т.е. «Дэн». Но если есть более одного слова, он возвращает результаты для каждого ключевого слова. т.е. «Дэн Райан», «Райан Дэн». Я также пробовал запрос с подстановочными знаками и префиксом, но они дают аналогичные результаты.

Нужно ли создавать собственный анализатор или есть какой-то другой способ обойти эту проблему?


person krosullivan    schedule 31.01.2013    source источник


Ответы (1)


Сначала я бы занялся этим на уровне отображения. Токенизатор ключевых слов сделает все ваше поле одним токеном, а затем добавление фильтра нижнего регистра приведет к тому, что все будет строчным... делая поле нечувствительным к регистру:

"analysis":{
    "analyzer":{
       "analyzer_firstletter":{
          "tokenizer":"keyword",
          "filter":"lowercase"
     }
 }

После вставки некоторых данных вот что содержит индекс:

$ curl -XGET localhost:9200/test2/tweet/_search -d '{
   "query": {
      "match_all" :{}
    }
  }' | grep title

    "title" : "river dog"
    "title" : "data"
    "title" : "drive"
    "title" : "drunk"
    "title" : "dzone"

Обратите внимание на запись «речная собака», которую вы хотите избежать. Теперь, если мы используем запрос match_phrase_prefix, вы будете сопоставлять только те, которые начинаются с 'd':

 $ curl -XGET localhost:9200/test2/tweet/_search -d '{
    "query": {
       "match_phrase_prefix": {
          "title": {
             "query": "d",
             "max_expansions": 5
          }
        }
      }
    }' | grep title

   "title" : "drive"
   "title" : "drunk"
   "title" : "dzone"
   "title" : "data"

Это не специфично для Elastica, но его должно быть довольно легко преобразовать в соответствующие команды. Важной частью является анализатор keyword + lowercase, а затем использование запроса match_phrase_prefix.

В качестве побочного примечания, подстановочные знаки очень медленные, и их лучше избегать, где это возможно :)

person Zach    schedule 31.01.2013
comment
Я на самом деле делал это, в значительной степени. Но я не думаю, что мой анализатор вызывался на этапе запроса. Я также должен сказать, что у меня тоже есть search_analyzer, который ведет себя стандартно. Затем я пытался переключить анализатор, когда был вызван запрос. т.е. $elasticaQueryString-›setAnalyzer('alphaAnalyzer'); Я пересмотрю и попробую ваш метод снова. - person krosullivan; 31.01.2013
comment
О, еще одна вещь, которую я только что понял: вы используете Query_String. Этот запрос разделит ваш поисковый текст по пробелам до того, как он достигнет анализатора, что полностью разрушит предлагаемое сопоставление (потому что тогда он будет искать [river][dog] вместо [river dog] ) . Переключение на запрос соответствия должно исправить это. - person Zach; 31.01.2013
comment
Взято сюда через ваш блог. Отличный ответ - person Steve; 07.05.2014