如何对嵌套对象进行聚合 - Elasticsearch
How to do aggregation on nested objects - 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"
}
}
}
}
}
}
}
}
根据 documentation,您不能对具有 text
数据类型的字段进行聚合。它们必须具有 keyword
数据类型。
那么你不能以这种方式在 detail.attribute
字段上进行聚合: detail.attribute
字段不存储任何值:它是一个 object
数据类型 - 不是您在问题中所写的 nested
数据类型,这意味着它是其他字段的容器,例如 Size
、Brand
等。因此您应该针对 detail.attribute.Size
字段——如果这个字段是 keyword
数据类型——例如。
另一个可能的错误是您正在尝试 运行 对 text
数据类型的 term
查询 - title.list
的数据类型是什么场地?。 Term
查询是具有 keyword
数据类型的字段的特权,而 match
查询用于查询 text
数据类型
这是我用于嵌套聚合查询的内容,减去实际值名称。
实际字段是一个关键字,如前所述,它是必需的,它是嵌套 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
}
]
}
}
我是 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"
}
}
}
}
}
}
}
}
根据 documentation,您不能对具有
text
数据类型的字段进行聚合。它们必须具有keyword
数据类型。那么你不能以这种方式在
detail.attribute
字段上进行聚合:detail.attribute
字段不存储任何值:它是一个object
数据类型 - 不是您在问题中所写的nested
数据类型,这意味着它是其他字段的容器,例如Size
、Brand
等。因此您应该针对detail.attribute.Size
字段——如果这个字段是keyword
数据类型——例如。另一个可能的错误是您正在尝试 运行 对
text
数据类型的term
查询 -title.list
的数据类型是什么场地?。Term
查询是具有keyword
数据类型的字段的特权,而match
查询用于查询text
数据类型
这是我用于嵌套聚合查询的内容,减去实际值名称。 实际字段是一个关键字,如前所述,它是必需的,它是嵌套 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
}
]
}
}