elasticsearch - 如何使用 Elastic 对嵌套对象进行子聚合?
问题描述
我有以下模式来表示可以有多种变体的产品(例如:T 恤的尺寸):
{
"mappings": {
"properties": {
"id": {"type": "keyword"},
"name": {"type": "text"},
"variants": {
"type": "nested",
"properties": {
"inventory": {"type": "long"},
"customizations": {"type": "object"},
"customizations.name": {"type": "keyword"},
"customizations.value": {"type": "keyword"}
}
}
}
}
}
然后我可以使用它插入如下所示的产品数据:
{
"id": "prod-1",
"name": "Shirt Design 1",
"variants": [
{"inventory": 78, "customizations": [{"name": "size", "value": "L"}, {"name": "color", "value": "blue"}]},
{"inventory": 78, "customizations": [{"name": "size", "value": "M"}, {"name": "color", "value": "blue"}]},
{"inventory": 89, "customizations": [{"name": "size", "value": "S"}, {"name": "color", "value": "blue"}]}
]
}
{
"id": "prod-2",
"name": "Shirt Design 2",
"variants": [
{"inventory": 78, "customizations": [{"name": "size", "value": "L"}, {"name": "color", "value": "green"}]},
{"inventory": 78, "customizations": [{"name": "size", "value": "M"}, {"name": "color", "value": "green"}]}
]
}
在过滤/查询此索引时,我希望能够根据构成产品的自定义项来显示方面。这些自定义是用户提交的,因此不在我的控制范围内,但我们的想法是能够显示如下过滤器:
☐ Size:
- S (1)
- M (2)
- L (2)
☐ Color:
- blue (1)
- green (1)
现在,我可以使用以下查询正确地按自定义名称存储桶:
{
"size": 0,
"aggs": {
"skus": {
"nested": {
"path": "variants"
},
"aggs": {
"customization_names": {
"terms": {
"field": "variants.customizations.name"
}
}
}
}
}
}
这给了我以下桶:
"buckets": [
{
"doc_count": 2,
"key": "color"
},
{
"doc_count": 2,
"key": "size"
}
],
尝试进行子聚合以获取下面的实际自定义列表是我卡住的地方。我试过了:
{
"size": 0,
"aggs": {
"skus": {
"nested": {
"path": "variants"
},
"aggs": {
"customization_names": {
"terms": {
"field": "variants.customizations.name"
},
"aggs": {
"sub": {
"reverse_nested": {},
"aggs": {
"customization_values": {
"terms": {
"field": "variants.customizations.value"
}
}
}
}
}
}
}
}
}
}
不返回任何子存储桶:
buckets": [
{
"doc_count": 4,
"key": "color",
"sub": {
"doc_count": 2,
"customization_values": {
"buckets": [],
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0
}
}
},
{
"doc_count": 4,
"key": "size",
"sub": {
"doc_count": 2,
"customization_values": {
"buckets": [],
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0
}
}
}
],
如果我不使用reverse_nested
, 而不是空的子存储桶,我会在其中获得所有可能的值,因此我会得到子存储桶的red and blue
一部分。size
我最初将其customizations
作为 key => value 的映射,但也无法使其工作。但是,“自定义”的格式在这里有些可自定义。
到目前为止,我发现解决此问题的唯一方法是向自定义项添加一个字段,该字段是名称 + 值的 json 字符串表示形式。
// mapping:
"customizations.facet_code": {"type": "keyword"}
// data:
"customizations": [{"name": "size", "value": "M", "facet_code": "{name:size,value:M}"],
然后,我可以正确地进行存储,facet_code
并且我的应用程序可以反序列化它以再次将事物重新组合在一起。如果可能的话,我希望我能弄清楚如何“正确”地做到这一点。
解决方案
这样做的“正确”方法是也制作customizations
of 类型nested
,而不是object
. 也就是说:
{
"mappings": {
"properties": {
"id": {
"type": "keyword"
},
"name": {
"type": "text"
},
"variants": {
"type": "nested",
"properties": {
"inventory": {
"type": "long"
},
"customizations": {
"type": "nested", <-- This
"properties": {
"name": {
"type": "keyword"
},
"value": {
"type": "keyword"
}
}
}
}
}
}
}
}
然后查询将是
{
"size": 0,
"aggs": {
"skus": {
"nested": {
"path": "variants.customizations"
},
"aggs": {
"customization_names": {
"terms": {
"field": "variants.customizations.name"
},
"aggs": {
"customization_values": {
"terms": {
"field": "variants.customizations.value"
}
}
}
}
}
}
}
}
产生所有你需要的方面:
{
...
"aggregations":{
"skus":{
"doc_count":10,
"customization_names":{
"doc_count_error_upper_bound":0,
"sum_other_doc_count":0,
"buckets":[
{
"key":"color",
"doc_count":5,
"customization_values":{
"doc_count_error_upper_bound":0,
"sum_other_doc_count":0,
"buckets":[
{
"key":"blue",
"doc_count":3
},
{
"key":"green",
"doc_count":2
}
]
}
},
{
"key":"size",
"doc_count":5,
"customization_values":{
"doc_count_error_upper_bound":0,
"sum_other_doc_count":0,
"buckets":[
{
"key":"L",
"doc_count":2
},
{
"key":"M",
"doc_count":2
},
{
"key":"S",
"doc_count":1
}
]
}
}
]
}
}
}
}
推荐阅读
- javascript - 如何用 html 标签替换字符?(丰富的文字)
- ios - 如何在 React Native 中获取带有 UITableViewCellStyleSubtitle 的原生 UITableView?
- java - 如何通过返回对象的反射来检索类类型?
- tabs - 如何使用 JFXBadge
- sql - SQL将两列合并为一
- anylogic - 如何在anylogic中获得车道上的汽车数量?
- hibernate - 如何直接从 jpql 查询(休眠)构造自定义对象列表
- google-chrome - Chrome 仅将某些图像显示为 webp
- excel - 迭代时如何计算目录中所有文件的总和?
- mongodb - MongoDB - 聚合找到没有。条目日期明智的