Как сделать агрегацию на вложенных объектах - Elasticsearch
Я довольно новичок в Elasticsearch, поэтому, пожалуйста, потерпите меня. Это часть моего документа в ES.
{
"source": {
"detail": {
"attribute": {
"Size": ["32 Gb",4],
"Type": ["Tools",4],
"Brand": ["Sandisk",4],
"Color": ["Black",4],
"Model": ["Sdcz36-032g-b35",4],
"Manufacturer": ["Sandisk",4]
}
},
"title": {
"list": [
"Sandisk Cruzer 32gb Usb 32 Gb Flash Drive , Black - Sdcz36-032g"
]
}
}
}
Итак, чего я хочу добиться, так это найти лучшие три или три верхних попадания объекта атрибута. Например, если я ищу "sandisk", я хочу получить три атрибута: ["Size", "Color", "Model"]
или какие-либо атрибуты, основанные на агрегации лучших хитов. Итак, я сделал такой запрос
{
"size": 0,
"aggs": {
"categoryList": {
"filter": {
"bool": {
"filter": [
{
"term": {
"title.list": "sandisk"
}
}
]
}
},
"aggs": {
"results": {
"terms": {
"field": "detail.attribute",
"size": 3
}
}
}
}
}
}
Но, похоже, не работает. Как это исправить? Любые советы будут высоко оценены.
Это _mappings
, Это не полный, но я думаю, этого будет достаточно.
{
"catalog2_0": {
"mappings": {
"product": {
"dynamic": "strict",
"dynamic_templates": [
{
"attributes": {
"path_match": "detail.attribute.*",
"mapping": {
"type": "text"
}
}
}
],
"properties": {
"detail": {
"properties": {
"attMaxScore": {
"type": "scaled_float",
"scaling_factor": 100
},
"attribute": {
"dynamic": "true",
"properties": {
"Brand": {
"type": "text"
},
"Color": {
"type": "text"
},
"MPN": {
"type": "text"
},
"Manufacturer": {
"type": "text"
},
"Model": {
"type": "text"
},
"Operating System": {
"type": "text"
},
"Size": {
"type": "text"
},
"Type": {
"type": "text"
}
}
},
"description": {
"type": "text"
},
"feature": {
"type": "text"
},
"tag": {
"type": "text",
"fields": {
"raw": {
"type": "keyword"
}
}
}
}
},
"title": {
"properties": {
"en": {
"type": "text"
}
}
}
}
}
}
}
}
2 ответа
Согласно документации, вы не можете сделать агрегацию на поле, которое имеет
text
тип данных. Они должны иметьkeyword
тип данных.Тогда вы не можете сделать агрегацию на
detail.attribute
поле таким образом:detail.attribute
поле не хранит никакого значения: этоobject
тип данных - неnested
один, как вы написали в вопросе, это означает, что это контейнер для другого поля, какSize
,Brand
и т.д. Поэтому вы должны объединиться противdetail.attribute.Size
поле - если это былkeyword
тип данных - например.Другая вероятная ошибка заключается в том, что вы пытаетесь запустить
term
запрос наtext
тип данных - что такое тип данныхtitle.list
поле?.Term
запрос является прерогативой для поля, которое имеетkeyword
тип данных, в то время какmatch
запрос используется для запроса противtext
тип данных
Вот что я использовал для вложенного запроса aggs, за исключением фактических имен значений. Фактическое поле - это ключевое слово, которое, как уже упоминалось, является обязательным, является частью вложенного объекта JSON:
"STATUS_ID": {
"type": "keyword",
"index": "not_analyzed",
"doc_values": true
},
запрос
GET index name/_search?size=200
{
"aggs": {
"panels": {
"nested": {
"path": "nested path"
},
"aggs": {
"statusCodes": {
"terms": {
"field": "nested path.STATUS.STATUS_ID",
"size": 50
}
}
}
}
}
}
Результат
"aggregations": {
"status": {
"doc_count": 12108963,
"statusCodes": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "O",
"doc_count": 5912218
},
{
"key": "C",
"doc_count": 401586
},
{
"key": "E",
"doc_count": 135628
},
{
"key": "Y",
"doc_count": 3742
},
{
"key": "N",
"doc_count": 1012
},
{
"key": "L",
"doc_count": 719
},
{
"key": "R",
"doc_count": 243
},
{
"key": "H",
"doc_count": 86
}
]
}
}