elasticsearch,Java,Jquery,Json,elasticsearch" /> elasticsearch,Java,Jquery,Json,elasticsearch" />

Java 弹性搜索多重匹配得到错误结果

Java 弹性搜索多重匹配得到错误结果,java,jquery,json,elasticsearch,Java,Jquery,Json,elasticsearch,我将向Elastic Search发送一个查询,以查找具有与查询匹配的字段的所有段。 我们正在实现一个“免费搜索”,用户可以写任何他想要的文本,我们建立了一个查询,搜索这个文本抛出所有的段字段。 其中一个(或多个)字段包含此文本的每个段都应返回 例如: 我想得到所有的部分,其中与名称“托尼洛佩兹”。 每个段都有一个“名字”字段和一个“姓氏”字段 我们的服务生成的查询: "multi_match" : { "query": "tony lopez", "type": "best

我将向Elastic Search发送一个查询,以查找具有与查询匹配的字段的所有段。 我们正在实现一个“免费搜索”,用户可以写任何他想要的文本,我们建立了一个查询,搜索这个文本抛出所有的段字段。 其中一个(或多个)字段包含此文本的每个段都应返回

例如:

我想得到所有的部分,其中与名称“托尼洛佩兹”。 每个段都有一个“名字”字段和一个“姓氏”字段

我们的服务生成的查询:

  "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
示例不完全相同,如果您有一个名为firstname
lopez
和lastname
tony
的文档,它会找到它

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”),因此查询将在所有字段上应用相同的分析器。