减少CouchDB中的多个字段值



对于通知系统,我将用户消息存储在CouchDB中。我的文档结构看起来像这样:

{
   "_id": "bc325c2f6a99194ecab6e7bbae81b609",
   "_rev": "1-9745ddb21cefe3dbc8cc1f7f7bd8d11d",
   "uid": "bc325c2f6a99194ecab6e7bbae80eb29",
   "msg": "Hi there, here is a message for you!",
   "level": "warning",
   "status": "new",
   "created": 1467180077,
   "read": null
}

字段状态可以有两个值newread -我试图编写一个Map/Reduce视图,以返回特定用户的计数,其中有多少消息具有状态new和状态read

Map函数非常简单:

function(doc) {
  emit(doc.uid, doc.status);
}

返回如下内容:

| key                                | value
+------------------------------------+------------------------------
| bc325c2f6a99194ecab6e7bbae80eb29   | "read"
+------------------------------------+------------------------------
| bc325c2f6a99194ecab6e7bbae80eb29   | "read"
+------------------------------------+------------------------------
| bc325c2f6a99194ecab6e7bbae80eb29   | "read"
+------------------------------------+------------------------------
| bc325c2f6a99194ecab6e7bbae80eb29   | "new"
+------------------------------------+------------------------------
| bc325c2f6a99194ecab6e7bbae80eb29   | "new"

我现在正试图找出如何写一个减少函数,将产生这个:

| key                                | value
+------------------------------------+------------------------------
| bc325c2f6a99194ecab6e7bbae80eb29   | ["read":3, "new":2]
+------------------------------------+------------------------------

如果我使用这个reduce函数

function (key, values, rereduce) {
    return  values;
}

:

| key                                | value
+------------------------------------+------------------------------
| bc325c2f6a99194ecab6e7bbae80eb29   | ["read","read","read","new","new"]
+------------------------------------+------------------------------

我尝试使用return count(values),但它返回null

我似乎不知道该如何处理这件事。有谁能给我指路吗?

我的建议是发出uidstatus作为您的密钥,然后您将获得计数作为您的减少值。

首先,我们从map函数开始:
function (doc) {
  emit([ doc.uid, doc.status ]);
}

注意,我们只发出一个键,而不关心一个值。(在这种情况下我们不需要它)

然后,使用以下内置的reduce函数

_count

您的视图输出将包含如下键:(记住,我们不关心值)

  • [ "bc325c2f6a99194ecab6e7bbae80eb29", "read" ]
  • [ "bc325c2f6a99194ecab6e7bbae80eb29", "read" ]
  • [ "bc325c2f6a99194ecab6e7bbae80eb29", "read" ]
  • [ "bc325c2f6a99194ecab6e7bbae80eb29", "new" ]
  • [ "bc325c2f6a99194ecab6e7bbae80eb29", "new" ]

当您查询视图时,确保包含group=true(隐含的reduce=true)

你会注意到你的视图现在有以下键/值对:

  • [ "bc325c2f6a99194ecab6e7bbae80eb29", "read" ]: 3
  • [ "bc325c2f6a99194ecab6e7bbae80eb29", "new" ]: 2

如果您的数据库中有更多的文档,那么您也将看到所有其他用户id。要过滤到您关心的用户,只需使用:

  • startkey=["bc325c2f6a99194ecab6e7bbae80eb29"]
  • endkey=["bc325c2f6a99194ecab6e7bbae80eb29",{}]

这些数组看起来有点奇怪,我敢肯定,但这些只是确保"状态"的任何值都将被匹配。(查看view Collation的文档获取更多信息)

这种方法可以很好地扩展,允许任何其他status值工作而无需任何代码更改。

我找到了这样做的方法,但我不确定这是否是正确的方法:

reduce函数:

function (key, values, rereduce) {
    var result = new Object;
    result.read = 0;
    result.new = 0;
    for(var i = 0; i < values.length; ++i){
        if(values[i] == 'new'){
                result.new++;
        }
            if(values[i] == 'read'){
                result.read++;
        }
    };
    return result;
}

将产生如下结果:

| key                                | value
+------------------------------------+------------------------------
| bc325c2f6a99194ecab6e7bbae80eb29   | {read: 2, new: 1}
+------------------------------------+------------------------------

相关内容

  • 没有找到相关文章

最新更新