3
votes

This is my document/mapping with a nested prices array:


    {
        "name": "Foobar",
        "type": 1,
        "prices": [
            {
                "date": "2016-03-22",
                "price": 100.41
            },
            {
                "date": "2016-03-23",
                "price": 200.41
            }
        ]
    }

Mapping:

    {
        "properties": {
          "name": {
            "index": "not_analyzed",
            "type": "string"
          },
          "type": {
            "type": "byte"
          },
          "prices": {
            "type": "nested",
            "properties": {
              "date": {
                "format": "dateOptionalTime",
                "type": "date"
              },
              "price": {
                "type": "double"
              }
            }
          }
        }
    }

I use a top_hits aggregation to get the min price of the nested price array. I also have to filter the prices by date. Here is the query and the response:

POST /index/type/_search

    {
      "size": 0,
      "query": {
        "match_all": {}
      },
      "aggs": {
        "prices": {
          "nested": {
            "path": "prices"
          },
          "aggs": {
            "date_filter": {
              "filter": {
                "range": {
                  "prices.date": {
                    "gte": "2016-03-21"
                  }
                }
              },
              "aggs": {
                "min": {
                  "top_hits": {
                    "sort": {
                      "prices.price": {
                        "order": "asc"
                      }
                    },
                    "size": 1
                  }
                }
              }
            }
          }
        }
      }
    }

Response:

    {
      "took": 3,
      "timed_out": false,
      "_shards": {
        "total": 3,
        "successful": 3,
        "failed": 0
      },
      "hits": {
        "total": 2,
        "max_score": 0,
        "hits": [
        ]
      },
      "aggregations": {
        "prices": {
          "doc_count": 4,
          "date_filter": {
            "doc_count": 4,
            "min": {
              "hits": {
                "total": 4,
                "max_score": null,
                "hits": [
                  {
                    "_index": "index",
                    "_type": "type",
                    "_id": "4225796ALL2016061541031",
                    "_nested": {
                      "field": "prices",
                      "offset": 0
                    },
                    "_score": null,
                    "_source": {
                      "date": "2016-03-22",
                      "price": 100.41
                    },
                    "sort": [
                      100.41
                    ]
                  }
                ]
              }
            }
          }
        }
      }
    }

Is there a way to get the parent source document (or some fields from it) with _id="4225796ALL2016061541031" in the response (e.g. name)? A second query is not an option.

1
Where is 'name' field? Can you please share sample document and mapping of your index?Richa
A sample document is at the top of my question. I've added the mapping also.AlexK

1 Answers

4
votes

Instead of applying aggregations use query and inner_hits like :

{
"query": {
    "nested": {
       "path": "prices",
       "query": {
          "range": {
              "prices.date": {
                "gte": "2016-03-21"
              }
            }
       },
        "inner_hits": {
           "sort": {
                  "prices.price": {
                    "order": "asc"
                  }
                },
                "size": 1
          }
       }
     }
  }

Fetch data of parent_documentdata from _source and actual data from inner_hits.

Hope it helps