如何在ElasticSearch中对单个字段应用完全匹配,对多个字段应用完全不同?

时间:2018-11-07 19:48:54

标签: elasticsearch

我最近开始研究ElasticSearch,并且正在尝试搜索以下条件

I have following data i.e. as shown in image in my index.

我想在上述数据上对ENAME应用完全匹配,并在EID和ENAME上应用完全匹配。 为了匹配,我有字符串ABC。 因此结果应如下所示

[
  {"EID" :111, "ENAME" : "ABC"},
  {"EID" : 444, "ENAME" : "ABC"}
]

1 个答案:

答案 0 :(得分:1)

您可以通过结合term查询和terms aggregation来实现这一目标。

假设您具有以下mapping

PUT my_index
{
  "mappings": {
    "doc": {
      "properties": {
        "EID": {
          "type": "keyword"
        },
        "ENAME": {
          "type": "keyword"
        }
      }
    }
  }
}

并插入如下文档:

POST my_index/doc/3
{
  "EID": "111",
  "ENAME": "ABC"
}

POST my_index/doc/4
{
  "EID": "222",
  "ENAME": "XYZ"
}

POST my_index/doc/12
{
  "EID": "444",
  "ENAME": "ABC"
}

将完成此工作的查询如下所示:

POST my_index/doc/_search
{
  "query": {
    "term": { 1️⃣
      "ENAME": "ABC"
    }
  },
  "size": 0, 3️⃣
  "aggregations": {
    "by EID": {
      "terms": { 2️⃣
        "field": "EID"
      }
    }
  }
}

让我解释一下它是如何工作的:

  • 1️⃣-term查询要求Elasticsearch过滤"ENAME"字段keyword的确切值;
  • 2️⃣-terms聚合收集另一个keyword字段"EID"的所有可能值的列表,并返回前N个最频繁的值;
  • 3️⃣-"size": 0告诉Elasticsearch不要返回任何搜索结果(我们只对聚合感兴趣)。

查询的输出将如下所示:

{
  "hits": {
    "total": 2,
    "max_score": 0,
    "hits": []
  },
  "aggregations": {
    "by EID": {
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": [
        {
          "key": "111",  <== Here is the first "distinct" value that we wanted 
          "doc_count": 3
        },
        {
          "key": "444", <== Here is another "distinct" value
          "doc_count": 2
        }
      ]
    }
  }
}

输出看起来与您在问题中发布的内容不完全相同,但是我相信这是您使用Elasticsearch可以获得的最接近的结果。

但是,此输出是等效的:

  • "ENAME"隐式存在(因为其值用于过滤)
  • "EID"位于“聚合”部分的"buckets"下。

请注意,在"doc_count"下,您会找到具有该"EID"的文档数。

如果我想在多个字段上进行DISTINCT怎么办?

对于更复杂的情况(例如,当您需要在许多字段上进行区别处理时),请参见this answer

有关聚合的更多信息,请参见here

希望有帮助!