Фильтр Elasticsearch Rails

#ruby-on-rails #elasticsearch #elasticsearch-rails

#ruby-on-rails #elasticsearch #elasticsearch-rails

Вопрос:

Я создаю веб-приложение Rails с помощью elasticsearch-model gem. Я хотел бы создать поисковый запрос с фильтрацией для моей модели места. Мне удалось выполнить поиск по имени, однако я хотел бы иметь возможность фильтровать свой поиск по городу (в данном примере Лондон).

На данный момент мой запрос выглядит следующим образом:

 "query": {
    "bool": {
      "must": {
        "match": {
          "name": {
            "query": term,
            "operator": "and",
            "fuzziness": 1
          }
        }
      },
      "filter": {
          "term": {
              "city": "London"
          }
      }
    }
  }
  

и чем я просто вызываю Place.search("here goes query").records.to_a

без фильтра поиск деталей работает нормально, но когда я добавляю фильтр, я не получаю никакого результата.

Это сопоставление для поиска места:

 settings analysis: {
    filter: {
        ngram_filter: {
            type: "nGram",
            min_gram: 2,
            max_gram: 20
        }
    },
    analyzer: {
        ngram_analyzer: {
            type: "custom",
            tokenizer: "standard",
            filter: [
                "lowercase",
                "asciifolding",
                "ngram_filter"
            ]
        },
        whitespace_analyzer: {
            type: "custom",
            tokenizer: "whitespace",
            filter: [
                "lowercase",
                "asciifolding"
            ]
        }
    }
} do
  mappings dynamic: 'false' do
    indexes :name,
            type: "string",
            analyzer: "ngram_analyzer",
            search_analyzer: "whitespace_analyzer"
  

Вот ссылка, которую я использовал, чтобы узнать, как фильтровать: документ Elasticsearch

Комментарии:

1. Одна из распространенных ошибок заключается в том, что данные разбиваются на то, что Elastic Search называет «токенами», на основе существующего токенизатора, и фильтр должен соответствовать токенам, которые они создают, а не тем, какие данные были первоначально проиндексированы. Например, после индексации поля со значением «AD-13» у меня были токены «ad» и «13», и поэтому «AD-13» не дал никаких результатов.

2. Я думаю, что я немного исправил, добавил indexes :city, type: "string" . Однако он работает только с городом, который состоит из одного слова и имеет нижний регистр, я думаю, что мне нужно поработать с анализатором, чтобы исправить это.

3. Анализатор, безусловно, является проблемой. Вы можете указать не анализировать поля, что я и сделал, чтобы избежать разбиения значений с пробелами на отдельные токены, что приводит к неправильному поиску.

Ответ №1:

Мне пришлось определить в сопоставлении тип города со строкой и не выполнять какой-либо анализ этого поля при создании токенов.

Итак, в сопоставлении я добавил:

 indexes :city,
        type: "string",
        index: "not_analyzed"