【问题标题】:ElasticSearch/Tire: How to properly set partial word searches upElasticSearch/Tire:如何正确设置部分单词搜索
【发布时间】:2013-03-13 23:11:52
【问题描述】:

尽管我看到很多关于它的报道都提到这一点相对简单,但我还没有设法看到它正常工作。假设我有这个:

class Car < ActiveRecord::Base
  settings analysis: {
    filter: {
      ngram_filter: { type: "nGram", min_gram: 3, max_gram: 12 }
    },
    analyzer: {
      partial_analyzer: {
        type: "snowball",
        tokenizer: "standard",
        filter: ["standard", "lowercase", "ngram_filter"]
      }
    }
  } do
    mapping do
      indexes :name,                    index_analyzer: "partial_analyzer"
    end
  end
end

假设我有一辆名为“福特”的汽车,我更新了我的索引。现在,如果我搜索“福特”:

Car.tire.search { query { string "Ford" } }

我的车在我的结果中。现在,如果我寻找“For”:

Car.tire.search { query { string "For" } }

我的车已经找不到了。我以为 nGram 过滤器会自动为我处理好它,但显然不是。作为临时解决方案,我使用通配符 (*) 进行此类搜索,但这绝对不是最好的方法,因为它是我搜索中的 min_gram 和 max_gram 定义关键元素。谁能告诉我他们是如何解决这个问题的?

我将 Rails 3.2.12 与 ruby​​ 1.9.3 一起使用。 ElasticSearch 版本是 0.20.5。

【问题讨论】:

    标签: ruby-on-rails elasticsearch tire


    【解决方案1】:

    您想使用自定义分析器而不是雪球分析器:Elasticsearch custom analyzer

    基本上,其他分析器都带有一组预定义的过滤器和标记器。

    您可能还想使用 Edge-Ngram 过滤器:Edge-Ngram filter

    Edge-NGram 和 NGram 的区别基本上是 Edge-Ngram 基本上只坚持一个术语的“边缘”。所以它从前面或后面开始。 Ford -> [For] 而不是 -> [For, ord]

    关于自动完成主题的一些更高级的链接:

    Autocompletion with fuzziness (pure elasticsearch, no tire, but very good read)

    Another useful question with links provided

    编辑

    基本上,我的设置与您的设置非常相似。但是对于标题和多字段的另一个分析器。由于多语言支持,这里是一个名称数组,而不仅仅是一个名称。

    我还指定了 search_analyzer,并使用字符串键而不是符号。这是我实际拥有的:

    settings "analysis" => {
        "filter" => {
            "name_ngrams"  => {
                "side"     => "front",
                "max_gram" => 20,
                "min_gram" => 2,
                "type"     => "edgeNGram"
            }
        },
        "analyzer" => {
            "full_name"     => {
                "filter"    => %w(standard lowercase asciifolding),
                "type"      => "custom",
                "tokenizer" => "letter"
            },
            "partial_name"        => {
                "filter"    => %w(standard lowercase asciifolding name_ngrams),
                "type"      => "custom",
                "tokenizer" => "standard"
            }
        }
    } do
      mapping do
        indexes :names do
          mapping do
            indexes :name, :type => 'multi_field',
                    :fields => {
                        "partial"           => {
                            "search_analyzer" => "full_name",
                            "index_analyzer"  => "partial_name",
                            "type"            => "string"
                        },
                        "title"      => {
                            "type"     => "string",
                            "analyzer" => "full_name"
                        }
                    }
          end
        end
      end
    end
    

    【讨论】:

    • 我已经使用了您的定义(自定义分析器、edge-n-gram 过滤器)并产生了相同的结果:“For”不返回任何内容,“Ford”返回所有内容。根据文档,它应该像你说的那样工作,我只是不知道为什么它不是。你在使用 Ruby/Tire 吗?
    • 是的,我正在使用轮胎和红宝石。您是否使用 rake 轮胎重新索引数据:import CLASS='Car' FORCE=true ?
    • 我做到了。使用 rake 任务和直接在控制台中删除/创建/导入。
    • 谢谢很多人,我今天没有时间验证它(有一些事情要做),但我希望明天会回到这个话题。
    猜你喜欢
    • 1970-01-01
    • 2012-04-21
    • 2011-09-21
    • 2016-01-07
    • 2016-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-11
    相关资源
    最近更新 更多