2

我有以下分析器(对雪球的设置方式稍作调整):

  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

我的索引中有一条带有 title 的记录foo bar

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

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

有人可以解释为什么,如果可能的话我怎么能得到它?

有人可以解释一下我如何才能让这个反向工作,以便如果我有一个带有标题foobar的记录,用户可以搜索foo bar并看到它作为结果?

谢谢

4

1 回答 1

2

您只能搜索索引中的标记。所以让我们看看你在索引什么。您当前正在使用lowercase标记器(它标记非字母字符上的字符串并将它们小写)然后应用standard过滤器(冗余,因为您没有使用standard标记器),stopandsnowball过滤器。

如果我们创建该分析器:

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

并使用analyzeAPI 对其进行测试:

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

你会看到"foo bar"产生了 terms["foo","bar"]"foobar"产生了 term ["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""foobar"使用match查询进行搜索,那么查询将成为查找任何这些标记的查询,其中一些标记存在于索引中。

不幸的是,它也会与"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取决于您的数据 - 尝试一下。

于 2013-02-08T09:43:43.367 回答