【问题标题】:Join of reverse_nested aggregations in Elasticsearch在 Elasticsearch 中加入 reverse_nested 聚合
【发布时间】:2016-04-23 17:03:43
【问题描述】:

请帮助我找到一种机制来聚合以下域或证明它在当前 API 中不存在。

    curl -XDELETE 127.0.0.1:9200/test_index

    curl -XPUT 127.0.0.1:9200/test_index -d '{
        "mappings": {
            "contact": {
                "properties": {
                    "facebook_profile": {
                        "type": "nested",
                        "properties": {
                            "education": {
                                "type": "string"
                            },
                            "year": {
                                "type": "integer"
                            }
                        }
                    },
                    "google_profile": {
                        "type": "nested",
                        "properties": {
                            "education": {
                                "type": "string"
                            },
                            "year": {
                                "type": "integer"
                            }
                        }
                    }
                }
            }
        }
    }'

    curl -XPUT 127.0.0.1:9200/test_index/contact/contact1 -d '{
        "google_profile": {
            "education": "stanford", "year": 1990
        }
    }'

    curl -XPUT 127.0.0.1:9200/test_index/contact/contact2 -d '
    {
        "facebook_profile": {
            "education": "stanford", "year": 1990
        }
    }'

如何查询 ES 以找到有关从特定大学毕业的联系人数量的统计数据?

我发现了一种可能性,但它没有给我想要的结果,因为它无法回答上述关于联系人的问题,而只能回答他们的特定个人资料(嵌套文档):

    curl -XPOST '127.0.0.1:9200/test_index/_search?search_type=count&pretty=true' -d '{
        "aggs": {
            "facebook_educations": {
                "aggs": {
                    "field": {
                        "terms": {
                            "field": "contact.facebook_profile.education"
                        },
                        "aggs": {
                            "reverse": {
                                "reverse_nested": {
                                }
                            }
                        }
                    }
                },
                "nested": {
                    "path": "contact.facebook_profile"
                }
            },
            "google_educations": {
                "aggs": {
                    "field": {
                        "terms": {
                            "field": "contact.google_profile.education"
                        },
                        "aggs": {
                            "reverse": {
                                "reverse_nested": {
                                }
                            }
                        }
                    }
                },
                "nested": {
                    "path": "contact.google_profile"
                }
            }
        }
    }'

什么给了我:

    "aggregations" : {
        "facebook_educations" : {
          "doc_count" : 1,
          "field" : {
            "doc_count_error_upper_bound" : 0,
            "sum_other_doc_count" : 0,
            "buckets" : [ {
              "key" : "stanford",
              "doc_count" : 1,
              "reverse" : {
                "doc_count" : 1
              }
            } ]
          }
        },
        "google_educations" : {
          "doc_count" : 1,
          "field" : {
            "doc_count_error_upper_bound" : 0,
            "sum_other_doc_count" : 0,
            "buckets" : [ {
              "key" : "stanford",
              "doc_count" : 1,
              "reverse" : {
                "doc_count" : 1
              }
            } ]
          }
        }
    }

但在这里我无法确定找到的联系人是相同还是不同的文档(父母),我分别无法回答我最初的问题。

感谢您的建议。

【问题讨论】:

    标签: elasticsearch


    【解决方案1】:

    听起来您正在尝试aggregate on multiple fields。 Elasticsearch 不直接支持这一点,但有一些方法可以解决这个问题并获得您正在寻找的结果。

    查看discussion on Github,以及documentation

    如果我理解正确,“stanford”是否出现在 facebook_profile.educationgoogle_profile.education 中,您希望 contact 在聚合中只计算一次。

    您应该能够通过以下两种方式之一执行此操作:

    1. 使用脚本连接存储在字段中的值:

      {
        "aggs": {
          "by_education": {
            "terms": {
              "script": "doc['contact.facebook_profile.education'].values + doc['contact.google_profile.education'].values"
            }
          }
        }
      }
      
    2. 您可以使用copy_to 选项在索引时创建一个包含两个字段值的新专用字段。然后在单个字段上聚合。例如,您可以将这两个字段的内容复制到一个名为 education_combined 的新字段中。

      {
        "mappings":{
          "contact":{
            "properties":{
              "facebook_profile":{
                "type":"nested",
                "properties":{
                  "education":{
                    "type":"string",
                    "copy_to":"education_combined"
                  },
                  "year":{
                    "type":"integer"
                  }
                }
              },
              "google_profile":{
                "type":"nested",
                "properties":{
                  "education":{
                    "type":"string",
                    "copy_to":"education_combined"
                  },
                  "year":{
                    "type":"integer"
                  }
                }
              },
              "education_combined":{
                "type":"string"
              }
            }
          }
        }
      }
      

      然后,简单地在education_combined上聚合:

      {
        "aggs": {
          "by_education": {
            "terms": { "field": "education_combined" }
          }
        }
      }
      

    【讨论】:

    • 您的第一个建议根本行不通,因为对于嵌套文档,您必须访问 _source 字段。第二个选项可能有效,但不幸的是在我的情况下不是,因为我已将嵌套文档包装到子文档中,并且我正在尝试执行某种 has_parent 聚合。这就是我现在所拥有的 stackoverflow.com/questions/35061945/… 。还是谢谢你
    猜你喜欢
    • 2017-10-08
    • 1970-01-01
    • 2021-09-19
    • 1970-01-01
    • 1970-01-01
    • 2017-09-24
    • 2014-11-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多