Search code examples
javaelasticsearchelastic-stackresthighlevelclient

How to group by field type for matched document fields?


I am using term aggregation to count the field values but before to aggregation i am doing filter search based on the result aggregation will work.. finally i need the id's and aggregation count for example if exception id is 1 and if it get matches then i need output as

1 -> "key": "transfer" "doc_count": 2

2 -> "key": "stock" "doc_count": 4

and i have highlighted the exception id in the below which i want as a pointer to each bucket.

How can i do it in elastic search i have attached the sample response.

{
  "took": 250,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 1,
      "relation": "eq"
    },
    "max_score": 0.0,
    "hits": [
      {
        "_index": "america",
        "_type": "_doc",
        "_id": "1",
        "_score": 0.0,
        "_source": {
          "clusterId": "1",
          "rank": 1,
          "events": [
            {
              "eventId": "1",
              "eventType": "Delayed",
              "metaInfo": {
                "batch_id": "batch_1"
              },
              "recommendationData": [
                {
                  ***"exceptionId": "1",***
                  "item": "Item1",
                  "location": "DC1",
                  "dueDate": "2019-01-10T05:30:00.000+0530",
                  "quantity": 100,
                  "metaInfo": {
                    "batch_id": "batch_1",
                    "dummy_id": "dummy_1"
                  },
                  "rank": 1,
                  "recommendations": [
                    {
                      "rank": 1,
                      "recommendationType": "transfer",
                      "customerName": "Walmart",
                      "stockTransfer": {
                        "primaryRecommendation": true,
                        "priority": 1,
                        "sourceLocation": "DC3",
                        "metaInfo": 40,
                        "shipDate": "2019-01-09T05:30:00.000+0530",
                        "arrivalDate": "2019-01-10T05:30:00.000+0530",
                        "transportMode": "Road",
                        "transferCost": 200.0,
                        "maxQtyAvailableForTransfer": 40,
                        "totalQtyAtSource": 40
                      },
                      "expedite": null
                    },
                    {
                      "rank": 1,
                      "recommendationType": "transfer",
                      "customerName": "Walmart",
                      "stockTransfer": {
                        "primaryRecommendation": true,
                        "priority": 2,
                        "sourceLocation": "DC2",
                        "transferQuantity": 60,
                        "shipDate": "2019-01-09T05:30:00.000+0530",
                        "arrivalDate": "2019-01-10T05:30:00.000+0530",
                        "transportMode": "Road",
                        "transferCost": 600.0,
                        "maxQtyAvailableForTransfer": 100,
                        "totalQtyAtSource": 100
                      },
                      "expedite": null
                    }
                  ]
                }
              ]
            }
          ]
        }
      }
    ]
  },
  "aggregations": {
    "recommendationTypes": {
      "doc_count": 2,
      "recommendationTypes": {
        "doc_count_error_upper_bound": 0,
        "sum_other_doc_count": 0,
        "buckets": [
          {
            "key": "transfer",
            "doc_count": 2
          }
        ]
      }
    }
  }
}

Solution

  • If you want to aggregation on any exceptionId or recommendationType , both of which are inside nested objects, you need to use nested aggregation.

    Ex. If you have a document with two nested documents with exceptionId as 1 and 2. You want to aggregate on nested document with exceptionId as 2 , you need to use nested aggregation even if you are filtering using nested query in "query" part because entire document is returned even when a nested object matches and you have to specifically mention in aggregation that you want to aggregate on a particular nested object . Query

    {
      "aggs": {
        "recommendations": {
          "nested": {
            "path": "events.recommendationData"
          },
          "aggs": {
            "exception": {
              "filter": {
                "terms": {
                  "events.recommendationData.exceptionId": [
                    "2"
                  ]
                }
              },
              "aggs": {
                "exceptionIds": {
                  "terms": {
                    "field": "events.recommendationData.exceptionId.keyword",
                    "size": 10
                  },
                  "aggs": {
                    "recommendations": {
                      "nested": {
                        "path": "events.recommendationData.recommendations"
                      },
                      "aggs": {
                        "recommendationType": {
                          "terms": {
                            "field": "events.recommendationData.recommendations.recommendationType",
                            "size": 10
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
    

    Results:

    "aggregations" : {
        "recommendations" : {
          "doc_count" : 1,
          "exception" : {
            "doc_count" : 1,
            "exceptionIds" : {
              "doc_count_error_upper_bound" : 0,
              "sum_other_doc_count" : 0,
              "buckets" : [
                {
                  "key" : "2",
                  "doc_count" : 1,
                  "recommendations" : {
                    "doc_count" : 2,
                    "recommendationType" : {
                      "doc_count_error_upper_bound" : 0,
                      "sum_other_doc_count" : 0,
                      "buckets" : [
                        {
                          "key" : "transfer",
                          "doc_count" : 2
                        }
                      ]
                    }
                  }
                }
              ]
            }
          }
        }
      }