简体   繁体   中英

ElasticSearch: Access outer document fields from within an nested aggregated query

I have the following mapping:

{
    "dynamic": "strict",
    "properties": {
        "id": {
            "type": "string"
        },
        "title": {
            "type": "string"
        },
        "things": {
            "type": "nested",
            "properties": {
                "id": {
                    "type": "long"
                },
                "something": {
                    "type": "long"
                }
            }
        }
    }
}

I insert docs as follows (Python script):

body = {"id": 1, "title": "one", "things": [{"id": 1000, "something": 33}, {"id": 1001, "something": 34}, ]}
es.create(index_name, doc_type=doc_type, body=body, id=1)

body = {"id": 2, "title": "two", "things": [{"id": 1000, "something": 43}, {"id": 1001, "something": 44}, ]}
es.create(index_name, doc_type=doc_type, body=body, id=2)

body = {"id": 3, "title": "three", "things": [{"id": 1000, "something": 53}, {"id": 1001, "something": 54}, ]}
es.create(index_name, doc_type=doc_type, body=body, id=3)

I run following aggregation query:

{
  "query": {
    "match_all": {}
  },
  "aggs": {
    "things": {
      "aggs": {
        "num_articles": {
          "terms": {
            "field": "things.id",
            "size": 0
          },
          "aggs": {
            "articles": {
              "top_hits": {
                "size": 50
              }
            }
          }
        }
      },
      "nested": {
        "path": "things"
      }
    }
  },
  "size": 0
}

(so, I want a count of no. of times each "thing" appears, and against each thing a list of the articles in which each thing appears)

The query produces:

"key": 1000,
"doc_count": 3,
"articles": {
    "hits": {
        "total": 3,
        "max_score": 1,
        "hits": [{
            "_index": "test",
            "_type": "article",
            "_id": "2",
            "_nested": {
                "field": "things",
                "offset": 0
            },
            "_score": 1,
            "_source": {
                "id": 1000,
                "something": 43
            }
        }, {
            "_index": "test",
            "_type": "article",
            "_id": "1",
            "_nested": {
                "field": "things",
                "offset": 0
            },
            "_score": 1,
            "_source": {
                "id": 1000,
                "something": 33
            }

.... (and so on)

What I'd like is for each hit to list all the fields from the "outer" or top-level document ie in this case, id and title.

Is this actually possible ..... and if so how ???

I'm not sure if this is what you're looking for, but let's give it a try:

{
  "query": {
    "match_all": {}
  },
  "aggs": {
    "nested_things": {
      "nested": {
        "path": "things"
      },
      "aggs": {
        "num_articles": {
          "terms": {
            "field": "things.id",
            "size": 0
          },
          "aggs": {
            "articles": {
              "top_hits": {
                "size": 50
              }
            },
            "reverse_things": {
              "reverse_nested": {},
              "aggs": {
                "title": {
                  "terms": {
                    "field": "title",
                    "size": 0
                  }
                },
                "id": {
                  "terms": {
                    "field": "id",
                    "size": 0
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

This produces something like this:

          "buckets": [
               {
                  "key": 1000,
                  "doc_count": 3,
                  "reverse_things": {
                     "doc_count": 3,
                     "id": {
                        "buckets": [
                           {
                              "key": "1",
                              "doc_count": 1
                           },
                           {
                              "key": "2",
                              "doc_count": 1
                           },
                           {
                              "key": "3",
                              "doc_count": 1
                           }
                        ]
                     },
                     "title": {
                        ...
                     }
                  },
                  "articles": {
                     "hits": {
                        "total": 3,
                        "max_score": 1,
                        "hits": [
                           {
                              "_index": "test",
                              "_type": "article",
                              "_id": "AVPOgQQjgDGxUAMojyuY",
                              "_nested": {
                                 "field": "things",
                                 "offset": 0
                              },
                              "_score": 1,
                              "_source": {
                                 "id": 1000,
                                 "something": 53
                              }
                           },
                           ...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM