带时间戳过滤的CouchDB Count Reduce

时间:2019-01-15 15:32:48

标签: couchdb cloudant

假设我有这样的文件:

{ 
  _id: "a98798978s978dd98d", 
  type: "signature", 
  uid: "u12345", 
  category: "cat_1", 
  timestamp: UNIX_TIMESTAMP 
}

我的目标是能够计算由某个signature创建的所有uid,但能够按timestamp进行过滤

感谢 Alexis ,到目前为止,我已经使用了reduce _count函数:

function (doc) {
  if (doc.type === "signature") {
    emit([doc.uid, doc.timestamp], 1);
  }
}

使用以下查询:

start_key=[null,lowerTimestamp]
end_key=[{},higherTimestamp]
reduce=true
group_level=1

响应:

{
  "rows": [
    {
      "key": [ "u11111" ],
      "value": 3
    },
    {
      "key": [ "u12345" ],
      "value": 26
    }
  ]
}

它可以正确计数uid,但过滤器无法正常工作。起初我以为可能是CouchDB 2.2错误,但是我尝试使用Cloudant并得到了相同的响应。

有人对我如何使它变得可操作以过滤时间戳记有任何想法吗?

1 个答案:

答案 0 :(得分:2)

在MapReduce中使用复合键(即,键是事物的数组)时,无法查询缺少“前导”数组元素的键范围。也就是说,您可以查询一定范围的uuid并按时间戳将结果排序,但是您的用例却相反-您想按时间查询uuid。

我很想把时间放在数组的第一位,但是unix时间戳对于分组不是很好;)。我不知道您的应用程序的来龙去脉,但是如果您要为 date 而不是像这样的时间戳编制索引,则为:

function (doc) {
  if (doc.type === "signature") {
    var date = new Date(doc.timestamp)
    var datestr = date.toISOString().split('T')[0]
    emit([datestr, doc.uuid], 1);
  }
}

这将允许您查询日期范围(到一整天的分辨率):

?startkey=["2018-01-01"]&endkey=["2018-02-01"]&group_level=2

尽管您的uuid按天分组。