Проверка орфографии Ngram для упругого поиска не работает с рельсами

Я использовал в своей модели проверку орфографии, чтобы, если пользователь вводит данные, такие как "Rentaal", он должен получать правильные данные как "Rental"

код document.rb

require 'elasticsearch/model'

class Document < ApplicationRecord
  include Elasticsearch::Model
  include Elasticsearch::Model::Callbacks
  belongs_to :user

  Document.import force: true


  def self.search(query)
  __elasticsearch__.search({
      query: {
        multi_match: {
          query: query,
          fields: ['name^10', 'service']
      }
    }
    })
  end


  settings index: { 
    "number_of_shards": 1, 
    analysis: {
      analyzer: {
        edge_ngram_analyzer: { type: "custom", tokenizer: "standard", filter: 
          ["lowercase", "edge_ngram_filter", "stop", "kstem" ] },
            }
        },
        filter: {
                  edge_ngram_filter: { type: "edgeNGram", min_gram: "3", max_gram: 
                  "20" } 
      }
    } do
    mapping do
      indexes :name, type: "string", analyzer: "edge_ngram_analyzer"
      indexes :service, type: "string", analyzer: "edge_ngram_analyzer"
    end 
  end
end

код контроллера поиска:

def search
  if params[:query].nil?
    @documents = []
  else
    @documents = Document.search params[:query]
  end
end

Однако, если я ввожу Rentaal или любое слово с ошибкой, оно ничего не отображает. В моей консоли

     @documents.results.to_a 

дает пустой массив.

Что я здесь не так делаю? Дайте мне знать, если потребуется больше данных.

1 ответ

Решение

Попробуй добавить fuzziness в вашем multi_match запрос:

{
      "query": {
        "multi_match": {
          "query": "Rentaal",
          "fields": ["name^10", "service"],
          "fuzziness": "AUTO"
      }
    }
}

объяснение

Фильтр Kstem используется для приведения слов к их корневым формам, и он не работает так, как вы ожидаете, - он будет обрабатывать такие фразы как Renta или же Rent, но не опечатка, которую вы предоставили.

Вы можете проверить, как работает stemming с помощью следующего запроса:

curl -X POST \
  'http://localhost:9200/my_index/_analyze?pretty=true' \
  -d '{
  "analyzer" : "edge_ngram_analyzer",
  "text" : ["rentaal"]
}'

В результате я вижу:

{
    "tokens": [
        {
            "token": "ren"
        },
        {
            "token": "rent"
        },
        {
            "token": "renta"
        },
        {
            "token": "rentaa"
        },
        {
            "token": "rentaal"
        }
    ]
}

Таким образом, типичное опечатка будет обрабатываться намного лучше с применением нечеткости.

Другие вопросы по тегам