按复合字段 (copy_to) 聚合在 Elasticsearch 上不起作用
Aggregation by a compound field (copy_to) not working on Elasticsearch
我在 Elasticsearch (v 1.5.0) 中有一个索引,其映射如下所示:
{
"storedash": {
"mappings": {
"outofstock": {
"_ttl": {
"enabled": true,
"default": 1296000000
},
"properties": {
"CompositeSKUProductId": {
"type": "string"
},
"Hosts": {
"type": "nested",
"properties": {
"HostName": {
"type": "string"
},
"SKUs": {
"type": "nested",
"properties": {
"CompositeSKUProductId": {
"type": "string",
"index": "not_analyzed"
},
"Count": {
"type": "long"
},
"ProductId": {
"type": "string",
"index": "not_analyzed",
"copy_to": [
"CompositeSKUProductId"
]
},
"SKU": {
"type": "string",
"index": "not_analyzed",
"copy_to": [
"CompositeSKUProductId"
]
}
}
}
}
},
"Timestamp": {
"type": "date",
"format": "dateOptionalTime"
}
}
}
}
}
}
查看字段 CompositeSKUProductId 是如何创建为 SKU 和 ProductId 字段的组合。
我现在想对 that 复合字段执行聚合,但它似乎不起作用;我查询的相关部分如下所示:
"aggs": {
"hostEspecifico": {
"filter": {
"term": { "Hosts.HostName": "www.example.com"}
},
"aggs": {
"skus": {
"nested": {
"path": "Hosts.SKUs"
},
"aggs": {
"valores": {
"terms": {
"field": "Hosts.SKUs.CompositeSKUProductId", "order": { "media": "desc" }, "size": 100 },
"aggs": {
"media": {
"avg": {
"field": "Hosts.SKUs.Count"
}
}
}
}
}
}
}
}
}
事情是,这个聚合返回了零个桶,就好像它根本不存在一样。
我检查了如果我将 CompositeSKUProductId 更改为 ProductId.
等另一个字段,则相同的查询是否有效
关于如何解决我的问题有什么想法吗?
N.B.: 我正在使用 AWS Elasticsearch Service,它不允许编写脚本。
为了 copy_to
嵌套文档中的另一个字段,您需要在映射中提供要复制到的字段的完整路径。您只提供了 "CompositeSKUProductId",这会导致数据被复制到您的根文档中的一个字段,而不是您的嵌套 SKU 类型文档。
尝试将 "SKUs" 类型的映射更新为 copy_to
完全限定字段 "Hosts.SKUs.CompositeSKUProductId"。
像这样:
{
"storedash": {
"mappings": {
"outofstock": {
"_ttl": {
"enabled": true,
"default": 1296000000
},
"properties": {
"CompositeSKUProductId": {
"type": "string"
},
"Hosts": {
"type": "nested",
"properties": {
"HostName": {
"type": "string"
},
"SKUs": {
"type": "nested",
"properties": {
"CompositeSKUProductId": {
"type": "string",
"index": "not_analyzed"
},
"Count": {
"type": "long"
},
"ProductId": {
"type": "string",
"index": "not_analyzed",
"copy_to": [
"Hosts.SKUs.CompositeSKUProductId"
]
},
"SKU": {
"type": "string",
"index": "not_analyzed",
"copy_to": [
"Hosts.SKUs.CompositeSKUProductId"
]
}
}
}
}
},
"Timestamp": {
"type": "date",
"format": "dateOptionalTime"
}
}
}
}
}
}
您可能会发现 this discussion 有帮助,当在 github 上打开类似问题时。
这里的问题是您误解了 copy_to
功能的概念。它只是复制各个字段的字段值,不会按照您期望的方式组合。
如果 SKU 是 123,产品 ID 是 456,那么复合字段会将它们作为 单独的值 而不是 123 456。您可以通过查询您的字段来验证这一点。
您必须在服务器端执行此操作,最好使用脚本,但这是不允许的。我们个人使用 AWS ES 服务但面临多个问题,主要是无法更改 elasticsearch.yml 文件并且无法使用脚本。你可能想看看 Found.
希望对您有所帮助!
我在 Elasticsearch (v 1.5.0) 中有一个索引,其映射如下所示:
{
"storedash": {
"mappings": {
"outofstock": {
"_ttl": {
"enabled": true,
"default": 1296000000
},
"properties": {
"CompositeSKUProductId": {
"type": "string"
},
"Hosts": {
"type": "nested",
"properties": {
"HostName": {
"type": "string"
},
"SKUs": {
"type": "nested",
"properties": {
"CompositeSKUProductId": {
"type": "string",
"index": "not_analyzed"
},
"Count": {
"type": "long"
},
"ProductId": {
"type": "string",
"index": "not_analyzed",
"copy_to": [
"CompositeSKUProductId"
]
},
"SKU": {
"type": "string",
"index": "not_analyzed",
"copy_to": [
"CompositeSKUProductId"
]
}
}
}
}
},
"Timestamp": {
"type": "date",
"format": "dateOptionalTime"
}
}
}
}
}
}
查看字段 CompositeSKUProductId 是如何创建为 SKU 和 ProductId 字段的组合。
我现在想对 that 复合字段执行聚合,但它似乎不起作用;我查询的相关部分如下所示:
"aggs": {
"hostEspecifico": {
"filter": {
"term": { "Hosts.HostName": "www.example.com"}
},
"aggs": {
"skus": {
"nested": {
"path": "Hosts.SKUs"
},
"aggs": {
"valores": {
"terms": {
"field": "Hosts.SKUs.CompositeSKUProductId", "order": { "media": "desc" }, "size": 100 },
"aggs": {
"media": {
"avg": {
"field": "Hosts.SKUs.Count"
}
}
}
}
}
}
}
}
}
事情是,这个聚合返回了零个桶,就好像它根本不存在一样。
我检查了如果我将 CompositeSKUProductId 更改为 ProductId.
等另一个字段,则相同的查询是否有效关于如何解决我的问题有什么想法吗?
N.B.: 我正在使用 AWS Elasticsearch Service,它不允许编写脚本。
为了 copy_to
嵌套文档中的另一个字段,您需要在映射中提供要复制到的字段的完整路径。您只提供了 "CompositeSKUProductId",这会导致数据被复制到您的根文档中的一个字段,而不是您的嵌套 SKU 类型文档。
尝试将 "SKUs" 类型的映射更新为 copy_to
完全限定字段 "Hosts.SKUs.CompositeSKUProductId"。
像这样:
{
"storedash": {
"mappings": {
"outofstock": {
"_ttl": {
"enabled": true,
"default": 1296000000
},
"properties": {
"CompositeSKUProductId": {
"type": "string"
},
"Hosts": {
"type": "nested",
"properties": {
"HostName": {
"type": "string"
},
"SKUs": {
"type": "nested",
"properties": {
"CompositeSKUProductId": {
"type": "string",
"index": "not_analyzed"
},
"Count": {
"type": "long"
},
"ProductId": {
"type": "string",
"index": "not_analyzed",
"copy_to": [
"Hosts.SKUs.CompositeSKUProductId"
]
},
"SKU": {
"type": "string",
"index": "not_analyzed",
"copy_to": [
"Hosts.SKUs.CompositeSKUProductId"
]
}
}
}
}
},
"Timestamp": {
"type": "date",
"format": "dateOptionalTime"
}
}
}
}
}
}
您可能会发现 this discussion 有帮助,当在 github 上打开类似问题时。
这里的问题是您误解了 copy_to
功能的概念。它只是复制各个字段的字段值,不会按照您期望的方式组合。
如果 SKU 是 123,产品 ID 是 456,那么复合字段会将它们作为 单独的值 而不是 123 456。您可以通过查询您的字段来验证这一点。
您必须在服务器端执行此操作,最好使用脚本,但这是不允许的。我们个人使用 AWS ES 服务但面临多个问题,主要是无法更改 elasticsearch.yml 文件并且无法使用脚本。你可能想看看 Found.
希望对您有所帮助!