小编典典

Elasticsearch with Tire:带多个单词的edgeNgram

elasticsearch

假设我有5个电影片名:

  • Sans Soleil
  • Sansa
  • So Is This
  • Sol Goode
  • Sole Survivor

我想使用此预期行为实现自动完成搜索字段:

  • “Sans” > Sans Soleil, Sansa
  • “Sans so” > Sans Soleil
  • “So” > So Is This, Sol Goode, Sole Survivor
  • “So Is” > So Is This
  • “Sol” > Sol Goode, Sole Survivor, Sans Soleil

这个用例似乎很明显,必须被许多人使用,但是我只是无法使其正常工作,而且我似乎也找不到任何答案或文档来提供帮助。这是我当前的模型:

class Film < Media
  include Tire::Model::Search
  include Tire::Model::Callbacks

  settings  :analysis => {
              :filter => {
                :title_ngram  => {
                  "type"      => "edgeNGram",
                  "min_gram"  => 2,
                  "max_gram"  => 8,
                  "side"      => "front" }
              },
              :analyzer => {
                :title_analyzer => {
                  "tokenizer"    => "lowercase",
                  "filter"       => ["title_ngram"],
                  "type"         => "custom" }
              }
            } do
    mapping do
      indexes :title, :type => 'string', :analyzer => 'title_analyzer'
      indexes :int_english_title, :type => 'string', :analyzer => 'title_analyzer'
    end
  end
end

以及如何在我的search_controller中处理查询:

search = Tire.search ['books', 'films', 'shows'], :load => true, :page => 1, :per_page => 10 do |s|
    s.query do |query|
        query.string "title:#{params[:search]}"
    end
end
@results = search.results

这会产生一些奇怪的行为:

  • “ Sans so”按此顺序返回“ Sansa,Sans Soleil,所以是这样”。
  • “按原样”按此顺序返回“ Sol Goode,Sans Soleil,唯一的幸存者,如此吗”。

阅读 288

收藏
2020-06-22

共1个答案

小编典典

我认为您可以通过将match查询设置为来实现所需的功能type:"phrase_prefix"。您的大多数(但不是全部)示例都可以使用。

使用Ngrams,您可以更好地控制该过程,但是它们的召回率很高(它们通常会返回想要的更多数据),因此您必须与之抗争。这是您在多个查询字词(“ Sans
so”)中观察到的“奇怪行为”,因为它们可以有效地作为Sans OR so查询执行。

尝试使用default_operator: "AND"选项(参见轮胎的query_string_test.rb),或者更确切地说,match查询(见轮胎的match_query_test.rb)与operator: "AND"选项。

有一些有关自动完成,轮胎和Ngrams的文章:

2020-06-22