示例数据:
PUT /test/test/1 { "text1":"cats meow", "text2":"12345", "text3":"toy" } PUT /test/test/2 { "text1":"dog bark", "text2":"98765", "text3":"toy" }
还有一个示例查询:
GET /test/test/_search { "size": 25, "query": { "multi_match" : { "fields" : [ "text1", "text2", "text3" ], "query" : "meow cats toy", "type" : "cross_fields" } } }
首先返回击中的猫,然后返回狗,这就是我想要的。
但是 当您查询时cat toy,猫和狗的相关性得分相同。我希望能够考虑到该单词的前缀(并且可能在该字段中添加了其他几个单词),然后运行cross_fields。
cat toy
cross_fields
因此,如果我搜索:
GET /test/test/_search { "size": 25, "query": { "multi_match" : { "fields" : [ "text1", "text2", "text3" ], "query" : "cat toy", "type" : "phrase_prefix" } } }
要么
GET /test/test/_search { "size": 25, "query": { "multi_match" : { "fields" : [ "text1", "text2", "text3" ], "query" : "meow cats", "type" : "phrase_prefix" } } }
我应该得到cat / ID 1,但没有。
我发现使用cross_fields可以实现多词短语,但不能实现多不完整的短语。并phrase_prefix获得不完整的短语,但不能获得多个不完整的短语…
phrase_prefix
筛选文档确实并没有帮助我发现如何结合这两者。
是的,我必须使用分析仪…
添加任何数据之前,在创建索引时将分析器应用于这些字段。添加数据后,我找不到更简单的方法来执行此操作。
我发现的解决方案是将所有短语分解成每个单独的前缀,因此cross_fields可以做到这一点。您可以在edge-ngram 此处了解有关使用的更多信息。
edge-ngram
因此,而不是cross_field只是搜索cats短语,它现在要搜索:c,ca,cat,和cats和每句话后......所以text1场将看起来像这样弹性:c ca cat cats m me meo meow。
cross_field
cats
c
ca
cat
text1
c ca cat cats m me meo meow
~~~
以下是使上述问题示例起作用的步骤:
首先,您创建并命名分析器。要了解多一点什么过滤器的值的含义,我建议你看看这个。
PUT /test { "settings": { "number_of_shards": 1, "analysis": { "filter": { "autocomplete_filter": { "type": "edge_ngram", "min_gram": 1, "max_gram": 20 } }, "analyzer": { "autocomplete": { "type": "custom", "tokenizer": "standard", "filter": [ "lowercase", "autocomplete_filter" ] } } } } }
然后,我将此分析仪附加到每个字段。我更改了,text1以匹配我将其应用到的字段。
PUT /test/_mapping/test { "test": { "properties": { "text1": { "type": "string", "analyzer": "autocomplete" } } } }
我跑来GET /test/_mapping确保一切正常。
GET /test/_mapping
然后添加数据:
POST /test/test/_bulk { "index": { "_id": 1 }} { "text1": "cats meow", "text2": "12345", "text3": "toy" } { "index": { "_id": 2 }} { "text1": "dog bark", "text2": "98765", "text3": "toy" }
和搜索!
{ "size": 25, "query": { "multi_match" : { "fields" : [ "text1", "text2", "text3" ], "query" : "cat toy", "type" : "cross_fields" } } }
哪个返回:
{ "took": 3, "timed_out": false, "_shards": { "total": 1, "successful": 1, "failed": 0 }, "hits": { "total": 2, "max_score": 0.70778143, "hits": [ { "_index": "test", "_type": "test", "_id": "1", "_score": 0.70778143, "_source": { "text1": "cats meow", "text2": "12345", "text3": "toy" } }, { "_index": "test", "_type": "test", "_id": "2", "_score": 0.1278426, "_source": { "text1": "dog bark", "text2": "98765", "text3": "toy" } } ] } }
当您搜索时cat toy,这会在两者之间形成对比,而之前的分数是相同的。但是现在,这cat首热门歌曲的得分更高了。这是通过考虑每个词组的每个前缀(在这种情况下/短语中最多20个字符),然后查看数据与的相关性来实现的cross_fields。