Как настроить поиск по дате и нечеткому названию наasticsearch - PullRequest
0 голосов
/ 12 февраля 2020

Я создаю приложение Rails 5 с Angular 7 фронтентом. В этом приложении я использую Searchkick (драгоценный камень Elasticsearch) и проиндексировал модель с именем Event, которая получила атрибуты title (string) и start_at (datetime).

Я хочу иметь возможность построить запрос в Контроллер поиска, где я могу сделать следующее:

  1. Поиск в заголовке с нечетким поиском, означающим, что он не должен соответствовать 100% (что сейчас требуется).
  2. Поиск с диапазоном дат, совпадающим с начальным значением для индексированных событий.

Это мой метод индекса контроллера

def index
        args = {}
        args[:eventable_id] = params[:id]
        args[:eventable_type] = params[:type]
        args[:title] = params[:title] if params[:title].present?
        if params[:starts_at].present?
            args[:starts_at] = {}
            args[:starts_at][:gte] = params[:starts_at].to_date.beginning_of_day
            args[:starts_at][:lte] = params[:ends_at].to_date.end_of_day
        end
        @events = Event.search where: args, page: params[:page], per_page: params[:per_page]
    end

Я добавил эту строку в Модель моего события

searchkick text_middle: [:title]

Это фактический запрос, который выполняется

{
    "query": {
        "bool": {
            "must": {
                "match_all": {}
            },
            "filter": [{
                "term": {
                    "eventable_id": "2"
                }
            }, {
                "term": {
                    "eventable_type": "Space"
                }
            }, {
                "term": {
                    "title": "nice event"
                }
            }, {
                "range": {
                    "starts_at": {
                        "from": "2020-02-01T00:00:00.000Z",
                        "include_lower": true,
                        "to": "2020-02-29T23:59:59.999Z",
                        "include_upper": true
                    }
                }
            }]
        }
    },
    "timeout": "11s",
    "_source": false,
    "size": 10000
}

Поиск по дате не работает (но я не получаю ошибок ) и поиск по названию должен совпадать на 100% (даже в случае).

Благодарю за помощь!

1 Ответ

0 голосов
/ 13 февраля 2020

Вместо использования нечетких запросов я бы порекомендовал анализатор ngram.

Вот пример анализатора ngram:

analyzer: {
    ngram_analyzer: {
        type: "custom",
        tokenizer: "standard",
        filter: ["lowercase", "ngram_filter"],
        char_filter: [
            "replace_dots"
        ]
    }
},
filter: {
    ngram_filter: {
        type: "ngram",
        min_gram: "3",
        max_gram: "20",
    }
}

Вам также нужно будет добавить этот код в индекс настроек:

 max_ngram_diff: 17

Затем на вашем отображении Убедитесь, что вы создали два поля. 1 отображение для вашего обычного поля, такого как name, а затем другое отображение для вашего поля ngram, такое как name.ngram.

В моем запросе я хотел бы увеличить поле name на 10, а поле name.ngram на 5, чтобы точные совпадения отображались первыми. Вы должны будете поиграть с этим, хотя.

Что касается вашего запроса диапазона, я использую gte и lte. Вот пример:

query:{
   bool: {
      must: {
          range: {date: {gte: params[:date], lte: params[:date], boost: 10}}
      }
   }
}

Надеюсь, это поможет.

...