动态数据聚合 / nested_objects
Aggregations with dynamic data / nested_objects
-
elasticsearch
-
elasticsearch-dsl
-
elasticsearch-aggregation
-
elasticsearch-painless
-
elasticsearch-scripting
我正在尝试在 ElasticSearch 中聚合动态映射的字段。
例如:
POST test/_doc/1
{
"settings": {
"range": {
"value": 200,
"display": "200 km"
},
"transmitter": {
"value": 1.2,
"display": "1.2 Ghz"
}
}
}
settings
下的属性是动态的。本质上我需要这样的查询:
{
"size": 0,
"query": {
"match_all": {}
},
"aggs": {
"settings": {
"terms": {
"field": "settings.*.display"
}
}
}
}
由于 *
在这里不起作用,我想知道是否有办法从无痛脚本 return 字段然后使用管道聚合?我在 JavaScript.
中找不到 Object.keys(settings)
的无痛等价物
我见过一种嵌套对象的方法,但我想避免这种情况,因为可能有很多 'settings' 属性并且 default limit 是 50,而 [=28] =] 具有 10000 个属性。
Object.keys()
的无痛等价物是 .keySet()
。您可以在脚本化指标聚合中实现以下迭代逻辑:
GET test/_search
{
"size": 0,
"aggs": {
"dynamic_fields_agg": {
"scripted_metric": {
"init_script": "state.map = [:];",
"map_script": """
def source = params._source['settings'];
for (def key : source.keySet()) {
if (source[key].containsKey("display")) {
if (state.map.containsKey(key)) {
state.map[key].add(source[key].display);
} else {
state.map[key] = [source[key].display];
}
}
}
""",
"combine_script": "return state",
"reduce_script": "return states"
}
}
}
}
这将产生类似于
的结果
{
"aggregations":{
"dynamic_fields_agg":{
"value":[
{
"map":{
"range":[
"200 km"
],
"transmitter":[
"1.2 Ghz"
]
}
}
]
}
}
}
现在您可以 post-process reduce/combine 脚本中的任何您喜欢的值。
在这里使用嵌套字段不会给您带来太多优势 -- 那里也不允许使用通配符路径。前段时间我asked that自己。
更新 -- 内联版本:
GET /test/_search
{ "size": 0, "aggs": { "dynamic_fields_agg": { "scripted_metric": { "init_script": "state.map = [:];", "map_script": " def source = params._source[\"settings\"];\n for (def key : source.keySet()) {\n if (source[key].containsKey(\"display\")) {\n if (state.map.containsKey(key)) { \n state.map[key].add(source[key].display);\n } else {\n state.map[key] = [source[key].display];\n }\n }\n }", "combine_script": "return state", "reduce_script": "return states" } } }}
elasticsearch
elasticsearch-dsl
elasticsearch-aggregation
elasticsearch-painless
elasticsearch-scripting
我正在尝试在 ElasticSearch 中聚合动态映射的字段。
例如:
POST test/_doc/1
{
"settings": {
"range": {
"value": 200,
"display": "200 km"
},
"transmitter": {
"value": 1.2,
"display": "1.2 Ghz"
}
}
}
settings
下的属性是动态的。本质上我需要这样的查询:
{
"size": 0,
"query": {
"match_all": {}
},
"aggs": {
"settings": {
"terms": {
"field": "settings.*.display"
}
}
}
}
由于 *
在这里不起作用,我想知道是否有办法从无痛脚本 return 字段然后使用管道聚合?我在 JavaScript.
Object.keys(settings)
的无痛等价物
我见过一种嵌套对象的方法,但我想避免这种情况,因为可能有很多 'settings' 属性并且 default limit 是 50,而 [=28] =] 具有 10000 个属性。
Object.keys()
的无痛等价物是 .keySet()
。您可以在脚本化指标聚合中实现以下迭代逻辑:
GET test/_search
{
"size": 0,
"aggs": {
"dynamic_fields_agg": {
"scripted_metric": {
"init_script": "state.map = [:];",
"map_script": """
def source = params._source['settings'];
for (def key : source.keySet()) {
if (source[key].containsKey("display")) {
if (state.map.containsKey(key)) {
state.map[key].add(source[key].display);
} else {
state.map[key] = [source[key].display];
}
}
}
""",
"combine_script": "return state",
"reduce_script": "return states"
}
}
}
}
这将产生类似于
的结果{
"aggregations":{
"dynamic_fields_agg":{
"value":[
{
"map":{
"range":[
"200 km"
],
"transmitter":[
"1.2 Ghz"
]
}
}
]
}
}
}
现在您可以 post-process reduce/combine 脚本中的任何您喜欢的值。
在这里使用嵌套字段不会给您带来太多优势 -- 那里也不允许使用通配符路径。前段时间我asked that自己。
更新 -- 内联版本:
GET /test/_search
{ "size": 0, "aggs": { "dynamic_fields_agg": { "scripted_metric": { "init_script": "state.map = [:];", "map_script": " def source = params._source[\"settings\"];\n for (def key : source.keySet()) {\n if (source[key].containsKey(\"display\")) {\n if (state.map.containsKey(key)) { \n state.map[key].add(source[key].display);\n } else {\n state.map[key] = [source[key].display];\n }\n }\n }", "combine_script": "return state", "reduce_script": "return states" } } }}