I have a parent-children mapping in ElasticSearch:
parent: user
children: privileges
For privileges there are a few properties, and one is "privilegeName".
The query returns users which have certain privileges, but I would like to return the aggregated privilegeNames for each user for the privileges that match the has_child
query.
I can return all privileges with inner_hits
and process them on the client side, but that may be cumbersome.
Is there a possibility to aggregate the inner_hits
?
Thanks
The inner hits feature can be used for this. This feature returns per search hit in the search response additional nested hits that caused a search hit to match in a different scope. Inner hits can be used by defining an inner_hits definition on a nested , has_child or has_parent query and filter.
Nested aggregationeditA special single bucket aggregation that enables aggregating nested documents. For example, lets say we have an index of products, and each product holds the list of resellers - each having its own price for the product.
A top_hits metric aggregator keeps track of the most relevant document being aggregated. This aggregator is intended to be used as a sub aggregator, so that the top matching documents can be aggregated per bucket.
I believe what you're looking for is the Children Aggregation.
For example, let's say I create the following index with the user as the parent, and privilege as the child:
PUT /my_index
{
"mappings": {
"user": {
"properties": {
"name": {
"type": "string"
},
"age": {
"type": "integer"
}
}
},
"privilege": {
"properties": {
"privilegeName": {
"type": "string"
}
},
"_parent": {
"type": "user"
}
}
}
}
Then, I add the following users:
PUT /my_index/user/1
{
"name": "sally",
"age": 32
}
PUT /my_index/user/2
{
"name":"bob",
"age": 41
}
Then I give each user some privileges. Let's say I give Sally the privilege to 'add','update' and 'delete':
POST /my_index/privilege/?parent=1
{
"privilegeName":"add"
}
POST /my_index/privilege/?parent=1
{
"privilegeName":"update"
}
POST /my_index/privilege/?parent=1
{
"privilegeName":"delete"
}
But I only give Bob the privilege to 'add' and 'update':
POST /my_index/privilege/?parent=2
{
"privilegeName":"add"
}
POST /my_index/privilege/?parent=2
{
"privilegeName":"update"
}
I can now search for all the users that have the 'add' privilege using the has_child
query. But, in the aggs
, I can also show a full list of all the privileges that each of the matching users has:
GET /my_index/user/_search
{
"query": {
"has_child": {
"type": "privilege",
"query": {
"match": {
"privilegeName": "add"
}
}
}
},
"aggs": {
"by_user": {
"terms": {
"field": "name"
},
"aggs": {
"to_privs": {
"children": {
"type": "privilege"
},
"aggs": {
"user_privs": {
"terms": {
"field": "privilegeName"
}
}
}
}
}
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With