Grouping rules
- Last UpdatedApr 14, 2026
- 2 minute read
The following rules apply regardless of which grouping mechanism you use (GroupByProperties, GroupByRelationships, or InRelationshipGroups).
Resource membership
|
Rule |
Detail |
|---|---|
|
No grouping = one summary |
When no grouping fields are set, all matching resources are folded into a single ResourceSummary with no group identity fields populated. |
|
Missing group-by property = excluded |
If a resource does not have the property used for GroupByProperty, it is excluded from all groups and does not appear in any ResourceSummary. It does not form its own catch-all group. |
|
Missing relationship = excluded |
If a resource has no targets for the relationship used in GroupByRelationship, it is excluded from all groups entirely. |
|
Multi-target = multi-group |
A resource linked to N targets via a relationship appears in N separate groups, contributing its values to each independently. |
|
External group membership |
A resource is included in an external group (InRelationshipGroups) if and only if its ID is explicitly listed in that group's Targets. Resources not listed in any group entry are excluded from all external groups. |
|
A resource can belong to multiple groups |
Both GroupByRelationship and InRelationshipGroups can place the same resource in more than one group simultaneously. |
Count semantics
|
Rule |
Detail |
|---|---|
|
ResourceSummary.Count |
Counts every resource that belongs to the group, regardless of whether it had a numeric value for any requested property. |
|
PropertySummary.Count |
Counts only the resources within the group that contributed a numeric value for that specific property. Always ≤ ResourceSummary.Count. |
|
Unauthorized resources |
Resources the caller cannot read are silently excluded from all aggregates and counts. The number of excluded resources is reported in Metrics.UnauthorizedGroupCount. |
Key cardinality
|
Rule |
Detail |
|---|---|
|
Multiple GroupByProperties |
Each unique combination of all group-by property values produces its own ResourceSummary. A resource that matches (alice, north) does not appear in (alice, south). |
|
Combining property and relationship groups |
Each unique combination of (property value tuple, relationship target) produces its own ResourceSummary. |
|
External groups + GroupByProperties |
Each unique combination of (external group key, property value tuple) produces its own ResourceSummary. |
|
Case-insensitive matching |
PropertyId, TypeId, and RelationshipId are matched case-insensitively. Group-by values (the actual property values used as keys) are also matched case-insensitively — "alice" and "ALICE" land in the same group. The value echoed back in the response is the stored value of the first matching resource. |
Property scoping (what gets summarized)
|
Rule |
Detail |
|---|---|
|
No TypeId = root only |
Omitting TypeId from SummarizeByProperty targets the root-level property exclusively. Component properties with the same PropertyId are ignored. |
|
With TypeId = that component only |
Providing TypeId targets that component exclusively. The root-level property with the same PropertyId is ignored. |
|
No cross-scope aggregation |
There is no mode that aggregates across multiple components or across root and component simultaneously. |