ruby-on-rails-3 - 在 Elasticsearch 中加入/拆分搜索词(使用轮胎)

标签 ruby-on-rails-3 elasticsearch tire fuzzy-search

我有以下分析器(对 snowball 的设置方式进行了轻微调整):

  string_analyzer: {
    filter: [ "standard", "stop", "snowball" ],
    tokenizer: "lowercase"
  }

这是它应用的领域:

  indexes :title, type: 'string', analyzer: 'string_analyzer'

  query do
    match ['title'], search_terms, fuzziness: 0.5, max_expansions: 10, operator: 'and'
  end

我的索引中有一条标题为 foo bar 的记录。

如果我搜索 foo bar,它会出现在结果中。

但是,如果我搜索 foobar,它不会。

有人能解释一下为什么吗?如果可能的话,我该如何做到这一点?

谁能解释一下我如何才能使它的反向工作也能正常工作,这样如果我有一个标题为 foobar 的记录,用户就可以搜索 foo bar 和结果呢?

谢谢

最佳答案

您只能搜索索引中的标记。因此,让我们看看您要编制索引的内容。 您当前正在使用 lowercase 分词器(它对非字母字符的字符串进行分词并将其转为小写),然后应用 standard 过滤器(冗余,因为您没有使用standard 分词器)、stopsnowball 过滤器。

如果我们创建那个分析器:

curl -XPUT 'http://127.0.0.1:9200/test/?pretty=1'  -d '
{
   "settings" : {
      "analysis" : {
         "analyzer" : {
            "string_analyzer" : {
               "filter" : [
                  "standard",
                  "stop",
                  "snowball"
               ],
               "tokenizer" : "lowercase"
            }
         }
      }
   }
}
'

并使用analyze API 对其进行测试:

curl -XGET 'http://127.0.0.1:9200/test/_analyze?pretty=1&text=foo+bar&analyzer=string_analyzer' 

您会看到 "foo bar" 生成术语 ["foo","bar"]"foobar" 生成术语["foobar"]。因此索引 "foo bar" 和搜索 "foobar" 目前无法工作。

如果您希望能够搜索“内部”词,则需要将词分解为更小的标记。为此,我们使用 ngram 分析器。

所以删除测试索引:

curl -XDELETE 'http://127.0.0.1:9200/test/?pretty=1' 

并指定一个新的分析器:

curl -XPUT 'http://127.0.0.1:9200/test/?pretty=1'  -d '
{
   "settings" : {
      "analysis" : {
         "filter" : {
            "ngrams" : {
               "max_gram" : 5,
               "min_gram" : 1,
               "type" : "ngram"
            }
         },
         "analyzer" : {
            "ngrams" : {
               "filter" : [
                  "standard",
                  "lowercase",
                  "ngrams"
               ],
               "tokenizer" : "standard"
            }
         }
      }
   }
}
'

现在,如果我们测试分析器,我们会得到:

"foo bar" => [f,o,o,fo,oo,foo,b,a,r,ba,ar,bar]
"foobar"  => [f,o,o,b,a,r,fo,oo,ob,ba,ar,foo,oob,oba,bar,foob,ooba,obar,fooba,oobar]

因此,如果我们索引 "foo bar" 并使用 match 查询来搜索 "foobar",那么查询就变成了查询寻找任何这些标记,其中一些存在于索引中。

不幸的是,它还会与 "wear the fox hat" 重叠(f,o,a).虽然 foobar 会出现在结果列表的较高位置,因为它有更多的共同标记,但您仍然会得到明显不相关的结果。

这可以通过使用 minimum_should_match 参数来控制,例如:

curl -XGET 'http://127.0.0.1:9200/test/test/_search?pretty=1'  -d '
{
   "query" : {
      "match" : {
         "my_field" : {
            "minimum_should_match" : "60%",
            "query" : "foobar"
         }
      }
   }
}
'

minimim_should_match 的确切值取决于您的数据 - 试验一下。

关于ruby-on-rails-3 - 在 Elasticsearch 中加入/拆分搜索词(使用轮胎),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14761671/

相关文章:

ruby-on-rails-3 - 在 Rails 3 中递归渲染集合

elasticsearch - EventFlow - 创建自定义过滤器以附加源服务器信息

Elasticsearch 5.6.16 补丁 log4j 与 2.16

mongodb - *** NoMethodError异常:未定义的方法 `_id'

ruby-on-rails - 如何在Rails 3应用程序中使用Dob日期时间字段搜索age_from至age_to?

ruby - 新 Rails 应用程序尝试在 "bundle install"上使用 jruby,而我希望它使用常规 ruby​​,有错误吗?

ruby-on-rails-3 - 在使用邮件程序 Rails 3 过滤之前

ruby-on-rails-3 - Railslongate_to不会使用自定义类名设置外键ID

elasticsearch - Elasticsearch 的得分范围是多少?

ruby-on-rails - 使用ElasticSearch和Tire按嵌套元素的数量排序