4

我将网站的每个页面视图保存在 ES 索引中,其中每个页面都由entity_id识别。我需要获取自给定时间点以来唯一页面浏览量的总数。我有以下映射:

{
   "my_index": {
      "mappings": {
         "page_views": {
            "_all": {
               "enabled": true
            },
            "properties": {
               "created": {
                  "type": "long"
               },
               "entity_id": {
                  "type": "integer"
               }
            }
         }
      }
   }
}

根据 Elasticsearch 文档,这样做的方法是使用基数聚合。这是我的搜索请求:

GET my_index/page_views/_search
{
  "filter": {
    "bool": {
      "must": [
        [
          {
            "range": {
              "created": {
                "gte": 9999999999
              }
            }
          }
        ]
      ]
    }
  },
  "aggs": {
    "distinct_entities": {
      "cardinality": {
        "field": "entity_id",
        "precision_threshold": 100
      }
    }
  }
}

请注意,我在未来使用了时间戳,因此不会返回任何结果。我得到的结果是:

{
   "took": 2,
   "timed_out": false,
   "_shards": {
      "total": 1,
      "successful": 1,
      "failed": 0
   },
   "hits": {
      "total": 0,
      "max_score": null,
      "hits": []
   },
   "aggregations": {
      "distinct_entities": {
         "value": 116
      }
   }
}

我不明白唯一页面访问量如何可能是 116,因为搜索查询根本没有页面访问量。我究竟做错了什么?

4

1 回答 1

3

您的聚合正在返回基数的全局值。如果您希望它只返回过滤集的基数,您可以这样做的一种方法是使用过滤器聚合,然后将您的基数聚合嵌套在其中。为了清楚起见,省略了过滤后的查询(您可以很容易地将其添加回来),我尝试的查询如下所示:

curl -XPOST "http://localhost:9200/my_index/page_views/_search " -d'
{
   "size": 0, 
   "aggs": {
      "filtered_entities": {
         "filter": {
            "bool": {
               "must": [
                  [
                     {
                        "range": {
                           "created": {
                              "gte": 9999999999
                           }
                        }
                     }
                  ]
               ]
            }
         },
         "aggs": {
            "distinct_entities": {
               "cardinality": {
                  "field": "entity_id",
                  "precision_threshold": 100
               }
            }
         }
      }
   }
}'

返回:

{
   "took": 1,
   "timed_out": false,
   "_shards": {
      "total": 5,
      "successful": 5,
      "failed": 0
   },
   "hits": {
      "total": 4,
      "max_score": 0,
      "hits": []
   },
   "aggregations": {
      "filtered_entities": {
         "doc_count": 0,
         "distinct_entities": {
            "value": 0
         }
      }
   }
}

这里有一些你可以玩的代码:

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

顺便说一句,我使用了 Elasticsearch 1.3.4。

于 2014-12-12T23:44:29.910 回答