3

我在我的模型中使用了拼写检查,这样如果用户输入像“Rental”这样的数据,那么它应该获取正确的数据作为“Rental”

文档.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 

给出一个空数组。

我在这里做错了什么?如果需要更多数据,请告诉我。

4

1 回答 1

2

尝试添加fuzziness您的multi_match查询:

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

解释

Kstem 过滤器用于将单词简化为它们的根形式,它在这里不能像您预期的那样工作 - 它可以正确处理 or 之类的短语RentaRent但不能处理您提供的拼写错误。

您可以使用以下查询检查词干提取的工作方式:

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"
        }
    ]
}

因此,应用模糊性可以更好地处理典型的拼写错误。

于 2017-07-31T07:02:16.627 回答