Я считаю, что вы ищете является Children Aggregation.
Например, предположим, что я создаю следующий индекс с пользователя в качестве родителя, и привилегия как ребенок:
PUT /my_index
{
"mappings": {
"user": {
"properties": {
"name": {
"type": "string"
},
"age": {
"type": "integer"
}
}
},
"privilege": {
"properties": {
"privilegeName": {
"type": "string"
}
},
"_parent": {
"type": "user"
}
}
}
}
Затем я добавил следующие пользователи:
PUT /my_index/user/1
{
"name": "sally",
"age": 32
}
PUT /my_index/user/2
{
"name":"bob",
"age": 41
}
Затем я предоставляю каждому пользователю некоторые привилегии. Скажем, я даю Салли привилегию «добавить», «обновление» и «удалить»:
POST /my_index/privilege/?parent=1
{
"privilegeName":"add"
}
POST /my_index/privilege/?parent=1
{
"privilegeName":"update"
}
POST /my_index/privilege/?parent=1
{
"privilegeName":"delete"
}
Но я только дать Бобу привилегию «добавить» и «обновление»:
POST /my_index/privilege/?parent=2
{
"privilegeName":"add"
}
POST /my_index/privilege/?parent=2
{
"privilegeName":"update"
}
Теперь я могу найти всех пользователей, у которых есть привилегия «добавить», используя запрос has_child
. Но, в aggs
, я могу также показать полный список всех привилегий, которые каждая из соответствующих пользователей имеет:
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"
}
}
}
}
}
}
}
}
агрегация детей является хорошей идеей. Однако есть проблема. Я хотел бы разбивать результаты на пользователя. Разбивка на страницы пользователей не учитывается для агрегатов. Есть ли способ сделать скопления только для фактических результатов, возвращаемых Запросом, учитывая разбиение на страницы? –
Это ответ от пользователей ES: «Внутренние хиты выполняют дополнительный поиск для каждого результата. Это уже может быть тяжелым, добавление агрегатов будет слишком большим. Скорее, запустите многопользовательский поиск с записью для каждого хита и вычислить скопления там ». –