我想从一个数组项与某个值匹配的文档系列中获取计数。
我有这样的文件:
{
"Name": "jason",
"Todos": [{
"State": "COMPLETED"
"Timer": 10
},{
"State": "PENDING"
"Timer": 5
}]
}
{
"Name": "jason",
"Todos": [{
"State": "COMPLETED"
"Timer": 5
},{
"State": "PENDING"
"Timer": 2
}]
}
{
"Name": "martin",
"Todos": [{
"State": "COMPLETED"
"Timer": 15
},{
"State": "PENDING"
"Timer": 10
}]
}
我想算一下我有多少个文档具有“已完成状态”的待办事项。然后按名称分组。
因此,从以上内容我将需要获得: 杰森:2 马丁:1
通常,我使用“名称”的术语聚合,以及其他项的其他子聚合:
"aggs": {
"statistics": {
"terms": {
"field": "Name"
},
"aggs": {
"test": {
"filter": {
"bool": {
"must": [{
"match_phrase": {
"SomeProperty.keyword": {
"query": "THEVALUE"
}
}
}
]
}
},
但是由于我的数组中有项目,所以不确定在这里如何做。
答案 0 :(得分:1)
Elasticsearch对数组没有问题,因为实际上flattens them by default:
内部对象字段的数组无法按您期望的方式工作。 Lucene没有内部对象的概念,因此Elasticsearch将对象层次结构简化为一个简单的字段名称和值列表。
因此,像您发布的查询一样的查询。不过,我将对term
使用keyword
datatype查询:
POST mytodos/_search
{
"size": 0,
"aggs": {
"by name": {
"terms": {
"field": "Name"
},
"aggs": {
"how many completed": {
"filter": {
"term": {
"Todos.State": "COMPLETED"
}
}
}
}
}
}
}
我假设您的映射看起来像这样:
PUT mytodos/_mappings
{
"properties": {
"Name": {
"type": "keyword"
},
"Todos": {
"properties": {
"State": {
"type": "keyword"
},
"Timer": {
"type": "integer"
}
}
}
}
}
您发布的示例文档将在内部转换为如下形式:
{
"Name": "jason",
"Todos.State": ["COMPLETED", "PENDING"],
"Todos.Timer": [10, 5]
}
但是,例如,如果您需要查询Todos.State
和 Todos.Timer
,则仅使用"COMPLETED"
过滤Timer > 10
,这种映射是不可能的,因为Elasticsearch忘记了对象数组项的字段之间的链接。
在这种情况下,您将需要使用nested
datatype之类的数组,并使用特殊的nested
query查询它们。
希望有帮助!