Elasticsearch 2.1.1嵌套聚合+cid基数统计结果异常求助
Hey there! Let's break down why you're seeing that unexpected cid=0 in your aggregation results and fix it up for Elasticsearch 2.1.1.
The Root Cause
Chances are your crankings field is a nested type (which makes sense for arrays of objects), and you're not wrapping your aggregation in a nested aggregation context. Without this, Elasticsearch treats nested documents as separate entries but doesn't properly link them to their parent document's cid value. This can lead to:
- Including parent documents that have no
crankingsentries at all (if yourcidfield has a default value of 0) - Mismatching
rank.rawvalues with unrelatedcids from other parent documents
Fixed Aggregation Query
Let's adjust your query to respect the nested structure and properly associate rank.raw values with their corresponding cids.
Scenario 1: cid is a field on the parent document
If cid lives at the root of your document (not inside the crankings nested array), you need to use reverse_nested to jump back to the parent context after grouping by rank.raw:
{ "size": 0, "aggs": { "nested_crankings_context": { "nested": { "path": "crankings" }, "aggs": { "group_by_rank": { "terms": { "field": "crankings.rank.raw" }, "aggs": { "return_to_parent": { "reverse_nested": {}, "aggs": { "unique_cids": { "cardinality": { "field": "cid", "missing": null // Ignore docs where cid is missing (avoids 0 defaults) } } } } } } } } } }
Scenario 2: cid is inside the crankings nested object
If cid is part of each nested crankings entry, you can skip the reverse_nested step and calculate cardinality directly in the nested context:
{ "size": 0, "aggs": { "nested_crankings_context": { "nested": { "path": "crankings" }, "aggs": { "group_by_rank": { "terms": { "field": "crankings.rank.raw" }, "aggs": { "unique_cids": { "cardinality": { "field": "crankings.cid", "missing": null // Ignore missing cid values in nested entries } } } } } } } }
Key Adjustments Explained
nestedAggregation: This locks us into the context of individualcrankingsentries, so we only process documents that actually have acrankingsvalue (eliminating those empty parent docs withcid=0).reverse_nested(when needed): Jumps back to the parent document context so we can count uniquecids that are associated with eachrank.rawgroup.missing: null: Tells Elasticsearch to ignore any documents (parent or nested) wherecidis missing, preventing default 0 values from being included in your cardinality count.
Quick Check
Double-check your mapping to confirm crankings is indeed marked as "type": "nested"—if it's a regular object type, the nested aggregation isn't needed, but object types flatten all fields, which can still cause mismatched cid counts. For arrays of objects, nested types are always the right choice to preserve document relationships.
内容的提问来源于stack exchange,提问作者Tushar

