[英]Elastic Search multi match gets wrong result
我正在向 Elastic Search 发送查询以查找具有与查询匹配的字段的所有段。 我们正在实现一个“免费搜索”,用户可以编写他想要的任何文本,我们构建一个查询,搜索这个文本会抛出所有的段字段。 其一个(或多个)字段具有此文本的每个段都应返回
例如:
我想获得所有名为“tony lopez”的片段。 每个段都有一个“first_name”字段和一个“last_name”字段。
我们的服务构建的查询:
"multi_match" : {
"query": "tony lopez",
"type": "best_fields"
"fields": [],
"operator": "OR"
}
使用此查询的 Elastic 的结果是包含“first_name”字段“tony”和“last_name”字段“lopez”的段,但也是“first_name”字段为“joe”且“last_name”为“tony”的段”。
在这种类型的查询中,我只想接收其名称为“tony (first_name) lopez (last_name)”的段
我该如何解决这个问题?
希望我不会过早下结论,但是如果您只想将tony
和lopez
作为名字和姓氏,请使用以下命令:
GET my_index/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"first": "tony"
}
},
{
"match": {
"last": "lopez"
}
}
]
}
}
}
但是,如果您的一个索引文档包含例如tony s
作为名字,则上面的查询也会返回它。
为什么? firstname
是text
数据类型
用于索引全文值的字段,例如 email 的正文或产品的描述。 对这些字段进行分析,也就是说,它们在被索引之前通过分析器将字符串转换为单个术语的列表。
如果您通过kibana
运行此查询:
POST my_index/_analyze
{
"field": "first",
"text": ["tony s"]
}
您将看到tony s
被分析为两个标记tony
和s
。
通过分析器将字符串转换为单个术语的列表(tony 作为术语,s 作为术语)。
这就是为什么上面的查询在结果中返回tony s
,它匹配tony
。
如果你只想得到tony
和lopez
完全匹配,那么你应该使用这个查询:
GET my_index/_search
{
"query": {
"bool": {
"must": [
{
"term": {
"first.keyword": {
"value": "tony"
}
}
},
{
"term": {
"last.keyword": {
"value": "lopez"
}
}
}
]
}
}
}
更新
试试这个查询——这与我的tony s
例子不是完全相同的问题,如果你有一个包含 firstname lopez
和 lastname tony
的文档,它会找到它。
GET my_index/_search
{
"query": {
"multi_match": {
"query": "tony lopez",
"fields": [],
"type": "cross_fields",
"operator":"AND",
"analyzer": "standard"
}
}
}
cross_fields 类型对于多个字段应该匹配的结构化文档特别有用。 例如,在查询 first_name 和 last_name 字段以查找“Will Smith”时,最佳匹配可能是一个字段中包含“Will”而另一个字段中包含“Smith”
希望能帮助到你
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.