【问题标题】:Elasticsearch, terms aggs according to sibling nested fieldsElasticsearch,根据兄弟嵌套字段的术语 aggs
【发布时间】:2020-02-17 18:12:49
【问题描述】:

Elasticsearch v7.5

你好,美好的一天!

我们有 2 个指数,分别名为 socialmediainfluencers

示例内容:

社交媒体

{
    '_id' : 1001,
    'title' : "Title 1",
    'smp_id' : 1,
    "latest" : [
        {
          "soc_mm_score" : "5",
        }
    ]
},
{
    '_id' : 1002,
    'title' : "Title 2",
    'smp_id' : 2,
    "latest" : [
        {
          "soc_mm_score" : "10",
        }
    ]
},
{
    '_id' : 1003,
    'title' : "Title 3",
    'smp_id' : 3,
    "latest" : [
        {
          "soc_mm_score" : "35",
        }
    ]
},
{
    '_id' : 1004,
    'title' : "Title 4",
    'smp_id' : 2,
    "latest" : [
        {
          "soc_mm_score" : "30",
        }
    ]
}

//省略了一些其他字段

影响者

{
    '_id' : 1,
    'name' : "John",
    'smp_id' : 1
},
{
    '_id' : 2,
    'name' : "Peter",
    'smp_id' : 2
},
{
    '_id' : 3,
    'name' : "Mark",
    'smp_id' : 3
}

现在我有了这个简单的查询,它可以确定 socialmedia 索引中的哪些 documents 具有最高的 latest.soc_mm_score 值,并显示它们的由smp_id

确定的对应influencers
GET socialmedia/_search
{
  "size": 0,
  "_source": "latest", 
  "query": {
    "match_all": {}
  }, 
  "aggs": {
    "LATEST": {
      "nested": {
        "path": "latest"
      },
      "aggs": {
        "MM_SCORE": {
          "terms": {
            "field": "latest.soc_mm_score",
            "order": {
              "_key": "desc"
            },
            "size": 3
          },
          "aggs": {
            "REVERSE": {
              "reverse_nested": {},
              "aggs": {
                "SMP_ID": {
                  "top_hits": {
                    "_source": ["smp_id"], 
                    "size": 1
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

样本输出

"aggregations" : {
    "LATEST" : {
      "doc_count" : //omitted,
      "MM_SCORE" : {
        "doc_count_error_upper_bound" : //omitted,
        "sum_other_doc_count" : //omitted,
        "buckets" : [
          {
            "key" : 35,
            "doc_count" : 1,
            "REVERSE" : {
              "doc_count" : 1,
              "SMP_ID" : {
                "hits" : {
                  "total" : {
                    "value" : 1,
                    "relation" : "eq"
                  },
                  "max_score" : 1.0,
                  "hits" : [
                    {
                      "_index" : "socialmedia",
                      "_type" : "index",
                      "_id" : "1003",
                      "_score" : 1.0,
                      "_source" : {
                        "smp_id" : "3"
                      }
                    }
                  ]
                }
              }
            }
          },
          {
            "key" : 30,
            "doc_count" : 1,
            "REVERSE" : {
              "doc_count" : 1,
              "SMP_ID" : {
                "hits" : {
                  "total" : {
                    "value" : 1,
                    "relation" : "eq"
                  },
                  "max_score" : 1.0,
                  "hits" : [
                    {
                      "_index" : "socialmedia",
                      "_type" : "index",
                      "_id" : "1004",
                      "_score" : 1.0,
                      "_source" : {
                        "smp_id" : "2"
                      }
                    }
                  ]
                }
              }
            }
          },
          {
            "key" : 10,
            "doc_count" : 1,
            "REVERSE" : {
              "doc_count" : 1,
              "SMP_ID" : {
                "hits" : {
                  "total" : {
                    "value" : 1,
                    "relation" : "eq"
                  },
                  "max_score" : 1.0,
                  "hits" : [
                    {
                      "_index" : "socialmedia",
                      "_type" : "index",
                      "_id" : "1002",
                      "_score" : 1.0,
                      "_source" : {
                        "smp_id" : "2"
                      }
                    }
                  ]
                }
              }
            }
          }
        ]
      }
    }
  }

通过上面的查询,我能够成功显示哪些文档具有最高的 latest.soc_mm_score

上面的示例输出仅显示 DOCUMENTS,说明与他们相关的 influencers (a.k.a smp_id) 是根据 latest.soc_mm_score 的 TOP INFLUENCERS强>

理想情况下,只需使用这个 aggs 查询,

"terms" : {
    "field" : "smp_id"
}

根据 doc_count

描绘了哪些影响者是 top 的概念

现在,根据 latest.soc_mm_score 显示术语查询会显示 TOP DOCUMENTS

"terms" : {
    "field" : "latest.soc_mm_score"
}

真正的目标

我想根据 socialmedia 索引中的 latest.soc_mm_count 显示 TOP INFLUENCERS。如果 Elasticsearch 可以根据唯一 smp_id 统计所有文档,那么 ES 有没有办法对所有 latest.soc_mm_score 值求和并将其用作 terms

我上面的目标应该输出这些:

  • smp_id 2 成为顶级影响者,因为他有 2 个帖子(soc_mm_score 分别为 30 和 10),添加它们可以获得 40 soc_mm_score
  • smp_id 3 作为第二大影响者,他有 1 个帖子,35 soc_mm_score
  • smp_id 1 作为第三大影响者,他有 1 个帖子获得 5 soc_mm_score

是否有合适的查询来满足这个目标?

【问题讨论】:

    标签: elasticsearch


    【解决方案1】:

    终于!找到答案了!!!

    "aggs": {
        "INFS": {
          "terms": {
            "field": "smp_id.keyword",
            "order": {
              "LATEST > SUM_SVALUE": "desc"
            }
          },
          "aggs": {
            "LATEST": {
              "nested": {
                "path": "latest"
              },
              "aggs": {
                "SUM_SVALUE": {
                  "sum" : {
                    "field": "latest.soc_mm_score"
                  }
                }
              }
            }
          }
        }
    }
    

    显示以下示例:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-06-19
      • 2015-04-08
      • 1970-01-01
      • 2019-08-10
      • 1970-01-01
      • 1970-01-01
      • 2019-08-29
      相关资源
      最近更新 更多