TLDR: Этот вариант использования использует name
/ value
внутри вложенного объекта для ограненных фильтров и агрегатов.
1 - Почему это лучше чем простое поле: значение в root документа без вложенного поля?
2 - Можете ли вы привести пример использования, который простое поле: значение не может обработать?
3. Почему в этом вопросе stackoverflow так сложно выполнить граненую агрегацию? Что мне не хватает?
Примечание: я знаю, что значение ключа во вложенной архитектуре позволяет иметь действительно ограниченное количество полей (ограничение по умолчанию равно 1000 для эластичного поиска), но в моем случае это не проблема, потому что Я знаю, что у меня будет ограниченное количество полей. Есть ли какое-то другое преимущество?
Подробности
Давайте попробуем создать граненую агрегацию для индекса только с полем: значение в root. Это индекс автомобиля:
PUT /car
{
"settings": {
"analysis": {
"normalizer": {
"govz_normalizer": {
"type": "custom",
"filter": [
"lowercase",
"asciifolding"
]
}
}
}
},
"mappings": {
"dynamic_templates": [
{
"simple_string": {
"mapping": {
"type": "keyword",
"normalizer": "govz_normalizer"
},
"path_match": "simple_string_*"
}
},
{
"simple_number": {
"mapping": {
"type": "double"
},
"path_match": "simple_number_*"
}
}
]
}
}
Это начальное число:
POST car/_doc
{"name": "car_name_1", "simple_string_brand": "Toyota", "simple_string_property": "luxury" }
POST car/_doc
{"name": "car_name_2", "simple_string_brand": "Ford","simple_string_property": "luxury" }
POST car/_doc
{"name": "car_name_3", "simple_string_brand": "Toyota", "simple_string_property": "sportive" }
POST car/_doc
{"name": "car_name_4", "simple_string_brand": "Honda", "simple_string_property": "city" }
POST car/_doc
{"name": "car_name_5", "simple_string_brand": "Toyota", "simple_string_property": "luxury" }
Мы видим, что граненые агрегаты работают отлично
GET car/_search
{
"query": {
"bool": {
"should": [
{
"match_all": {}
}
],
"filter": {
"bool": {
"must": [
{
"term": {
"simple_string_property": "luxury"
}
},
{
"term": {
"simple_string_brand": "toyota"
}
}
]
}
}
}
},
"aggs": {
"brand": {
"terms": {
"field": "simple_string_brand"
}
},
"property": {
"terms": {
"field": "simple_string_property"
}
}
}
}
Результат:
{
"took": 13,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 2,
"relation": "eq"
},
"max_score": 1.0,
"hits": [
{
"_index": "car",
"_type": "_doc",
"_id": "75",
"_score": 1.0,
"_source": {
"name": "car_name_1",
"simple_string_brand": "Toyota",
"simple_string_property": "luxury"
}
},
{
"_index": "car",
"_type": "_doc",
"_id": "33278",
"_score": 1.0,
"_source": {
"name": "car_name_5",
"simple_string_brand": "Toyota",
"simple_string_property": "luxury"
}
}
]
},
"aggregations": {
"property": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "luxury",
"doc_count": 2
}
]
},
"brand": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "toyota",
"doc_count": 2
}
]
}
}
}