您只能搜索索引中的标记。所以让我们看看你在索引什么。您当前正在使用lowercase
标记器(它标记非字母字符上的字符串并将它们小写)然后应用standard
过滤器(冗余,因为您没有使用standard
标记器),stop
andsnowball
过滤器。
如果我们创建该分析器:
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"
产生了 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
取决于您的数据 - 尝试一下。