如何在elasticsearch中进行嵌套字段内的复杂查询?

68bkxrlz  于 2023-01-29  发布在  ElasticSearch
关注(0)|答案(1)|浏览(165)

我有一些文档包含一个嵌套字段planList,它是一个对象数组。它的长度总是2或3。对象总是有3个键- planName,planType和planId。
我想写一个查询,它将返回一个所有planName的列表,沿着它出现的最频繁的计划和它的频率。
例如,考虑以下4个文档-

{planList: [{planName: a, planType: x, planId: 1},{planName: b, planType: x, planId: 2}]}
{planList: [{planName: a, planType: x, planId: 1},{planName: b, planType: x, planId: 2},{planName: c, planType: y, planId: 3}]}
{planList: [{planName: a, planType: x, planId: 1},{planName: c, planType: y, planId: 3}]}
{planList: [{planName: d, planType: y, planId: 4},{planName: c, planType: y, planId: 3}]}

对该数据的响应应具有以下见解-

plan A was found with plan B and plan C 2 times (draw between plan B and C)
plan B was found with plan A 2 times
plan C was found with plan A 2 times
plan D was found with plan C one time

查询这些文档非常简单-

"query": {
    "bool": {
      "must": [
        {
          "match": {
            "event": "comparePlans"
          }
        }
      ]
    }
  }

有人能帮助我获得我所寻找的洞察力所需的聚合吗?谢谢。
编辑:上述索引的Map如下所示-

"planList": {
   "type": "nested",
   "properties": {
     "planId": {
       "type": "keyword"
     },
     "planName": {
       "type": "keyword"
     },
     "planType": {
       "type": "keyword"
     }
   }
 },
"event": {
   "type": "keyword",
   "null_value": "none"
 }
sz81bmfz

sz81bmfz1#

据我所知,除了脚本聚合之外,没有完美的方法来完成它,但是,这是接近的。注意,这个聚合还计算计划名称的出现次数。
如果您知道相同的计划不能在数组中出现两次,那么您可以只得到这个答案,然后从每个时段中过滤掉相同的计划名称。
质询:

{
  "size": 0,
  "aggs": {
    "ALL_PLANS": {
      "nested": {
        "path": "planList"
      },
      "aggs": {
        "GROUPED_BY_NAME": {
          "terms": {
            "field": "planList.planName",
            "size": 10
          },
          "aggs": {
            "REVERSE_TO_ROOT": {
              "reverse_nested": {},
              "aggs": {
                "ALL_PLANS": {
                  "nested": {
                    "path": "planList"
                  },
                  "aggs": {
                    "GROUPED_BY_NAME": {
                      "terms": {
                        "field": "planList.planName",
                        "size": 10
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

回复:

{
  "took" : 4,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 4,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  },
  "aggregations" : {
    "ALL_PLANS" : {
      "doc_count" : 9,
      "GROUPED_BY_NAME" : {
        "doc_count_error_upper_bound" : 0,
        "sum_other_doc_count" : 0,
        "buckets" : [
          {
            "key" : "a",
            "doc_count" : 3,
            "REVERSE_TO_ROOT" : {
              "doc_count" : 3,
              "ALL_PLANS" : {
                "doc_count" : 7,
                "GROUPED_BY_NAME" : {
                  "doc_count_error_upper_bound" : 0,
                  "sum_other_doc_count" : 0,
                  "buckets" : [
                    {
                      "key" : "a",
                      "doc_count" : 3
                    },
                    {
                      "key" : "b",
                      "doc_count" : 2
                    },
                    {
                      "key" : "c",
                      "doc_count" : 2
                    }
                  ]
                }
              }
            }
          },
          {
            "key" : "c",
            "doc_count" : 3,
            "REVERSE_TO_ROOT" : {
              "doc_count" : 3,
              "ALL_PLANS" : {
                "doc_count" : 7,
                "GROUPED_BY_NAME" : {
                  "doc_count_error_upper_bound" : 0,
                  "sum_other_doc_count" : 0,
                  "buckets" : [
                    {
                      "key" : "c",
                      "doc_count" : 3
                    },
                    {
                      "key" : "a",
                      "doc_count" : 2
                    },
                    {
                      "key" : "b",
                      "doc_count" : 1
                    },
                    {
                      "key" : "d",
                      "doc_count" : 1
                    }
                  ]
                }
              }
            }
          },
          {
            "key" : "b",
            "doc_count" : 2,
            "REVERSE_TO_ROOT" : {
              "doc_count" : 2,
              "ALL_PLANS" : {
                "doc_count" : 5,
                "GROUPED_BY_NAME" : {
                  "doc_count_error_upper_bound" : 0,
                  "sum_other_doc_count" : 0,
                  "buckets" : [
                    {
                      "key" : "a",
                      "doc_count" : 2
                    },
                    {
                      "key" : "b",
                      "doc_count" : 2
                    },
                    {
                      "key" : "c",
                      "doc_count" : 1
                    }
                  ]
                }
              }
            }
          },
          {
            "key" : "d",
            "doc_count" : 1,
            "REVERSE_TO_ROOT" : {
              "doc_count" : 1,
              "ALL_PLANS" : {
                "doc_count" : 2,
                "GROUPED_BY_NAME" : {
                  "doc_count_error_upper_bound" : 0,
                  "sum_other_doc_count" : 0,
                  "buckets" : [
                    {
                      "key" : "c",
                      "doc_count" : 1
                    },
                    {
                      "key" : "d",
                      "doc_count" : 1
                    }
                  ]
                }
              }
            }
          }
        ]
      }
    }
  }
}

因此,我们可以看到"a"与"a"一起出现了3次(忽略这一点),与"b"和"c"一起出现了2次。

相关问题