#elasticsearch #kibana #aggregation #elasticsearch-aggregation
#elasticsearch #kibana #агрегирование #elasticsearch-агрегация
Вопрос:
Я отслеживаю посещаемость нескольких студентов. Я сохраняю их данные в индексе, как показано ниже.
В каждом документе в разделе «записи» есть несколько других полей. Следующие данные показывают, что ученик посетил 6 занятий в «понедельник».
«записи» имеют тип «вложенные».
{
reg_id: 1111,
"entires" : [
{
id: "123"
day: 'Monday'
},
{
id: "1234",
attendance: true
},
{
id: "12345",
classes_attended: 6
}
],
}
Я хочу, чтобы в каждом классе было подсчитано количество учеников за каждый день.
Например, «найдено 72 записи учащихся для «Понедельника», которые посещали 6 занятий».
Пример желаемого результата — это всего лишь пример, я полностью в порядке, если схема вывода будет изменена.
[
{
"day" : "monday",
"classes_attended": 6,
count: 4
},
{
"day" : "monday",
"classes_attended": 1,
count: 5
},
{
"day" : "tuesday",
"classes_attended": 5,
count: 2
},
{
"day" : "tuesday",
"classes_attended": 6,
count: 1
}
]
Не уверен, как начать с запроса агрегации:
Я попытался выполнить следующий запрос, но я знаю, что это неправильное решение
"aggs": {
"attendance_aggs": {
"nested": {
"path": "entries"
},
"aggs": {
"days": {
"terms": {
"field": "entries.day"
},
"aggs": {
"attended": {
"reverse_nested": {},
"aggs":{
"class_attended_day": {
"terms": {
"field": "entries.classes_attended"
},
"aggs": {
"class_attended_days_count": {
"reverse_nested": {},
"aggs": {
"classes_attended_final": {
"cardinality": {
"field": "entries.class_attended"
}
}
}
}
}
}
}
}
}
}
}
}
}
Ответ №1:
Неясно, что такое объект верхнего уровня, поэтому я предполагаю, что это «запись посещаемости учащихся за день». Я также не уверен, что entries.ids
они представляют, но предполагаю, что они понадобятся вам позже, поэтому я оставлю их нетронутыми.
Теперь, поскольку все, что у ваших entries
объектов общего, — это id
, они могут быть разделены. Это означает, что вы должны использовать nested
if any только в том случае, если вы используете некоторые атрибуты для всех объектов, которые нуждаются в сохранении их атрибутивных связей. Поскольку я нигде не вижу entries.id
в ваших agg, я бы рекомендовал внести следующие изменения в ваше сопоставление:
PUT students
{
"mappings": {
"properties": {
"day": { ------------
"type": "keyword" |
}, |
"attendance": { |
"type": "boolean" | <--
}, |
"classes_attended": { |
"type": "integer" |
}, ------------
"entries": {
"type": "nested",
"properties": {
"day": {
"type": "keyword",
"copy_to": "day" <--
},
"attendance": {
"type": "boolean",
"copy_to": "attendance" <--
},
"classes_attended": {
"type": "integer",
"copy_to": "classes_attended" <--
}
}
}
}
}
}
и вот ваш запрос:
GET students/_search
{
"size": 0,
"aggs": {
"days": {
"terms": {
"field": "day"
},
"aggs": {
"classes_attended": {
"terms": {
"field": "classes_attended"
},
"aggs": {
"student_count": {
"cardinality": {
"field": "_id"
}
}
}
}
}
}
}
}
Затем ответ может быть обработан постобработкой во все, что вы предпочитаете.
Редактировать
Вы можете перехватить reverse_nested
, но вам нужно будет вернуться к нему, поскольку вы ссылаетесь на другие вложенные записи:
GET students/_search
{
"size": 0,
"aggs": {
"attendance_aggs": {
"nested": {
"path": "entries"
},
"aggs": {
"days": {
"terms": {
"field": "entries.day"
},
"aggs": {
"attended": {
"reverse_nested": {},
"aggs": {
"class_attended_day": {
"nested": {
"path": "entries"
},
"aggs": {
"class_attended_day": {
"terms": {
"field": "entries.classes_attended"
},
"aggs": {
"classes_attended_final": {
"cardinality": {
"field": "entries.classes_attended"
}
}
}
}
}
}
}
}
}
}
}
}
}
}
Комментарии:
1. Спасибо, Джо. У меня есть ключ «submit_id», который является общим для всех вложенных объектов. Можно ли придерживаться самого вложенного типа и переписать запрос. Я также готов изменить отображение индекса. Но, к вашему сведению, я использую ключ, который является общим для всех вложенных объектов. Было бы здорово, если бы я мог получить запрос без изменения сопоставления.
2. Добавлена вложенная версия к моему ответу. Но просто для ясности — я не изменял вашу вложенность. Я сгладил атрибуты на верхнем уровне, потому что вам не нужны вложенные агги для получения вашего ответа.