Java 弹性搜索多重匹配得到错误结果
我将向Elastic Search发送一个查询,以查找具有与查询匹配的字段的所有段。 我们正在实现一个“免费搜索”,用户可以写任何他想要的文本,我们建立了一个查询,搜索这个文本抛出所有的段字段。 其中一个(或多个)字段包含此文本的每个段都应返回 例如: 我想得到所有的部分,其中与名称“托尼洛佩兹”。 每个段都有一个“名字”字段和一个“姓氏”字段 我们的服务生成的查询:Java 弹性搜索多重匹配得到错误结果,java,jquery,json,
elasticsearch,Java,Jquery,Json,
elasticsearch,我将向Elastic Search发送一个查询,以查找具有与查询匹配的字段的所有段。 我们正在实现一个“免费搜索”,用户可以写任何他想要的文本,我们建立了一个查询,搜索这个文本抛出所有的段字段。 其中一个(或多个)字段包含此文本的每个段都应返回 例如: 我想得到所有的部分,其中与名称“托尼洛佩兹”。 每个段都有一个“名字”字段和一个“姓氏”字段 我们的服务生成的查询: "multi_match" : { "query": "tony lopez", "type": "best
"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
作为firstname和lastname,请使用以下选项:
GET my_index/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"first": "tony"
}
},
{
"match": {
"last": "lopez"
}
}
]
}
}
}
但是如果您的一个索引文档包含例如tony s
作为firstname,那么上面的查询也会返回它
为什么?firstname
是一种text
数据类型
用于索引全文值的字段,如电子邮件正文或产品说明。对这些字段进行分析,也就是说,在索引之前,这些字段通过分析器将字符串转换为单个术语的列表
如果您通过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
示例不完全相同,如果您有一个名为firstnamelopez
和lastnametony
的文档,它会找到它
GET my_index/_search
{
"query": {
"multi_match": {
"query": "tony lopez",
"fields": [],
"type": "cross_fields",
"operator":"AND",
"analyzer": "standard"
}
}
}
交叉字段类型对于多个字段应该匹配的结构化文档特别有用。例如,在查询“Will Smith”的名字和姓氏字段时,最好的匹配可能是一个字段中有“Will”,另一个字段中有“Smith”
希望有帮助为问题添加更多的上下文总是更好的。如果您指定映射和一些示例数据,那就太好了。正确的结果是什么?谢谢您的回答!提到的每个字段数据类型都是“文本”。我们实现了一个“免费搜索”,您可以插入任何文本并接收该文本在其中一个字段中找到的片段。正确的结果是只有名为“tony”,姓为“lopez”的片段。谢谢您的回答!正如您的建议,我们正在实施“免费搜索”,您可以插入任何文本并接收在其中一个字段中找到的文本片段。因此,我对elastic的查询只是查询本身,没有指定要搜索的字段。我将编辑我的问题并添加这些关键信息。@RoyLeibovitz查看我的更新-向下滚动直到看到更新最新解决方案的问题是,名字和姓氏字段被分为两个不同的字段。因此,当我发送此查询时,我得到0个结果..我不明白。请共享您的映射。@RoyLeibovitz我刚才看到您使用的是一个自定义分析器,cross_fields将使用同一分析器的字段视为一个大字段。我更新了我的查询(添加了“analyzer”:“standard”),因此查询将在所有字段上应用相同的分析器。