在Elasticsearch字段上汇总和计算聚合

时间:2018-01-17 20:11:52

标签: elasticsearch elasticsearch-plugin elasticsearch-5

我是Elasticsearch的新手,我希望通过Elasticsearch 5.x索引对字段执行某些聚合。我有一个索引,其中包含字段langs(具有嵌套结构)和docLang的文档。这些是动态映射的字段。以下是示例文档

DOC 1:

{
   "_index":"A",
   "_type":"document",
   "_id":"1",
   "_source":{
      "text":"This is a test sentence.",
      "langs":{
         "X":{
            "en":1,
            "es":2,
            "zh":3
         },
        "Y":{
            "en":4,
            "es":5,
            "zh":6
         } 
      },
      "docLang": "en"
   }
}

DOC 2:

{
   "_index":"A",
   "_type":"document",
   "_id":"2",
   "_source":{
      "text":"This is a test sentence.",
      "langs":{
         "X":{
            "en":1,
            "es":2
         },
         "Y":{
            "en":3,
            "es":4
         } 
      },
      "docLang": "es"
   }
}

DOC 3:

{
   "_index":"A",
   "_type":"document",
   "_id":"2",
   "_source":{
      "text":"This is a test sentence.",
      "langs":{
         "X":{
            "en":1
         },
         "Y":{
            "en":2
         } 
      },
      "docLang": "en"
   }
}

我希望在langs字段上执行求和聚合,对于每个键(X / Y)和每种语言,我可以得到索引中所有文档的总和。另外,我想从docLang字段生成每种语言的文档计数。

例如:对于上述3个文档,langs字段的总和聚合如下所示:

"langs":{  
      "X":{  
         "en":3,
         "es":4,
         "zh":3
      },
      "Y":{  
         "en":9,
         "es":9,
         "zh":6
      }
   }

docLang计数如下所示:

 "docLang":{
    "en" : 2,
    "es" : 1
   }

另外由于一些生产env限制,我不能在Elasticsearch中使用脚本。所以,我想知道是否可以在上述字段中使用field聚合类型?

1 个答案:

答案 0 :(得分:1)

{
  "size": 0,
  "aggs": {
    "X": {
      "nested": {
        "path": "langs.X"
      },
      "aggs": {
        "X_sum_en": {
          "sum": {
            "field": "langs.X.en"
          }
        },
        "X_sum_es": {
          "sum": {
            "field": "langs.X.es"
          }
        },
        "X_sum_zh": {
          "sum": {
            "field": "langs.X.zh"
          }
        }
      }
    },
    "Y": {
      "nested": {
        "path": "langs.Y"
      },
      "aggs": {
        "Y_sum_en": {
          "sum": {
            "field": "langs.Y.en"
          }
        },
        "Y_sum_es": {
          "sum": {
            "field": "langs.Y.es"
          }
        },
        "Y_sum_zh": {
          "sum": {
            "field": "langs.Y.zh"
          }
        }
      }
    },
    "sum_docLang": {
      "terms": {
        "field": "docLang.keyword",
        "size": 10
      }
    }
  }
}

既然你没有提到,但我认为这很重要。我将XY设为nested字段:

    "langs": {
      "properties": {
        "X": {
          "type": "nested",
          "properties": {
            "en": {
              "type": "long"
            },
            "es": {
              "type": "long"
            },
            "zh": {
              "type": "long"
            }
          }
        },
        "Y": {
          "type": "nested",
          "properties": {
            "en": {
              "type": "long"
            },
            "es": {
              "type": "long"
            },
            "zh": {
              "type": "long"
            }
          }
        }
      }
    }

但是,如果你的字段根本不是nested,这里我的意思是Elasticsearch中的nested字段类型,像这样的简单聚合就足够了:

{
  "size": 0,
  "aggs": {
    "X_sum_en": {
      "sum": {
        "field": "langs.X.en"
      }
    },
    "X_sum_es": {
      "sum": {
        "field": "langs.X.es"
      }
    },
    "X_sum_zh": {
      "sum": {
        "field": "langs.X.zh"
      }
    },
    "Y_sum_en": {
      "sum": {
        "field": "langs.Y.en"
      }
    },
    "Y_sum_es": {
      "sum": {
        "field": "langs.Y.es"
      }
    },
    "Y_sum_zh": {
      "sum": {
        "field": "langs.Y.zh"
      }
    },
    "sum_docLang": {
      "terms": {
        "field": "docLang.keyword",
        "size": 10
      }
    }
  }
}