弹性搜索 - 使用嵌套的过滤数组作为存储桶

时间:2015-06-23 17:36:42

标签: arrays elasticsearch filtering aggregation bucket

我有点失落......

考虑这个简单的索引文档:

{
"url" : "http://...?mypage"
"pages": [
 {
  "elapsed": 1190,
  "type": "LOADPAGE"
 },
 {
  "elapsed": 115400,
  "type": "ONPAGE"
 },
 {
  "elapsed": 1100,
  "type": "LOADPAGE"
 },
 {
  "elapsed": 1340,
  "type": "ONPAGE"
 }
]    
}

我正在尝试计算平均LOADPAGE,所以我知道我需要“avg”或“stats”聚合。

"aggs": {
    "compute_loadpage": {
        "filter": { "term": { "pages.type": "loadpage" } },
        "aggs": {
            "loadpage_all": {
                "stats": {
                    "field": "pages.elapsed"
                }
            }
       }
    }
}

我知道“过滤器”会创建一个包含与我的过滤器对应的所有文档的存储桶,然后可以理解我的聚合将在我的完整“页面”数组上完成。

如何创建一个只有LOADPAGE值的存储桶,然后我就可以对它进行聚合,或者我必须使用脚本化的聚合?

1 个答案:

答案 0 :(得分:2)

只要您的文档映射使用nested aggregation,就可以使用nested type执行此操作。

为了测试,我设置了一个这样的简单索引(注意嵌套类型,"index": "not_analyzed"上的"pages.type"):

PUT /test_index
{
   "settings": {
      "number_of_shards": 1
   },
   "mappings": {
      "doc": {
         "properties": {
            "pages": {
               "type": "nested",
               "properties": {
                  "elapsed": {
                     "type": "long"
                  },
                  "type": {
                     "type": "string",
                     "index": "not_analyzed"
                  }
               }
            },
            "url": {
               "type": "string"
            }
         }
      }
   }
}

然后我将你的文件编入索引:

PUT /test_index/doc/1
{
   "url": "http://...?mypage",
   "pages": [
      {
         "elapsed": 1190,
         "type": "LOADPAGE"
      },
      {
         "elapsed": 115400,
         "type": "ONPAGE"
      },
      {
         "elapsed": 1100,
         "type": "LOADPAGE"
      },
      {
         "elapsed": 1340,
         "type": "ONPAGE"
      }
   ]
}

然后这个聚合似乎提供了你想要的东西:

POST /test_index/_search?search_type=count
{
   "aggs": {
      "pages_nested": {
         "nested": {
            "path": "pages"
         },
         "aggs": {
            "loadpage_filtered": {
               "filter": {
                  "term": {
                     "pages.type": "LOADPAGE"
                  }
               },
               "aggs": {
                  "loadpage_avg_elap": {
                     "avg": {
                        "field": "pages.elapsed"
                     }
                  }
               }
            }
         }
      }
   }
}
...
{
   "took": 3,
   "timed_out": false,
   "_shards": {
      "total": 1,
      "successful": 1,
      "failed": 0
   },
   "hits": {
      "total": 1,
      "max_score": 0,
      "hits": []
   },
   "aggregations": {
      "pages_nested": {
         "doc_count": 4,
         "loadpage_filtered": {
            "doc_count": 2,
            "loadpage_avg_elap": {
               "value": 1145,
               "value_as_string": "1145.0"
            }
         }
      }
   }
}

以下是我用来测试的代码:

http://sense.qbox.io/gist/b526427f14225b02e7268ed15d8c6dde4793fc8d