Javascript 使用mapreduce计算Cloudant中特定用户参与的事件数

Javascript 使用mapreduce计算Cloudant中特定用户参与的事件数,javascript,mapreduce,nosql,cloudant,Javascript,Mapreduce,Nosql,Cloudant,我正在使用Cloudant的map reduce功能,我想找到一个日期范围内(用户输入)具有名称的特定用户(用户输入)参加了多少事件(事件对象计数) 我的文档如下所示 { user: { name: 'peter pan' }, startEventDateTime: <timestamp>, endDateDateTime: <timestamp>, events: [ { name: 'La la land', text: 'more

我正在使用Cloudant的
map reduce
功能,我想找到一个日期范围内(用户输入)具有名称的特定用户(用户输入)参加了多少事件(事件对象计数)

我的文档如下所示

{
 user: {
  name: 'peter pan'
 },
 startEventDateTime: <timestamp>,
 endDateDateTime: <timestamp>,
 events: [
  {
    name: 'La la land',
    text: 'more info'
  },
  {
    name: 'La la land',
    text: 'more info'
  }
 ]
}
减少:

function (keys, values, rereduce) {
  if (rereduce) {
    return sum(values);
  } else {
    return values.length;
  }
}

我建议您考虑使用不同的文件格式。不要使用包含事件列表的用户文档,而是为每个事件创建一个单独的文档,并按事件发生的时间标记时间,例如:

{
  "_id": "c48ee0881ce7c5d39243d2243d2e63cb",
  "_rev": "1-c2f71fba5f09b129f1db20785f2429b2",
  "user": "bob",
  "datetime": "Thu 30 Nov 2017 09:46:02 GMT",
  "event": {
    "name": "lalaland",
    "text": "more info"
  }
}
然后,您可以依靠MapReduce为每个用户选择日期范围。下面是一个映射函数,它可以做到这一点:

function (doc) {
  if (doc && doc.user && doc.datetime) {
    var when = new Date(Date.parse(doc.datetime));
    emit([doc.user, when.getFullYear(), when.getMonth(), when.getDay()], 1);
  }
}
并使用内置的reduce
\u sum
。现在可以使用关键帧范围对数据进行切片。假设您希望用户
bob
参加2017年8月的活动:

curl 'https://ACCT.cloudant.com/DBNAME/_design/DDOC/_view/VIEWNAME?startkey=\["bob", 2017, 7\]&endkey=\["bob", 2017, 8]&group=true&inclusive_end=false&reduce=true'

{
  "rows": [
    {
      "key": [
        "bob",
        2017,
        7,
        4
      ],
      "value": 1
    }
  ]
}
curl 'https://ACCT.cloudant.com/DBNAME/_design/DDOC/_view/VIEWNAME?startkey=\["bob", 2017, 7\]&endkey=\["bob", 2017, 8]&group=true&inclusive_end=false&reduce=true'

{
  "rows": [
    {
      "key": [
        "bob",
        2017,
        7,
        4
      ],
      "value": 1
    }
  ]
}