减少CouchDB中的多个字段值

时间:2016-06-29 06:51:03

标签: mapreduce couchdb

对于通知系统,我将用户消息存储在CouchDB中。我的文档结构如下所示:

<Project ...>
  <ProjectGroup ...>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProjectGuid>{64D2C408-BB81-4627-AF7C-672142229677}</ProjectGuid>
    <OutputType>Library</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>Some.Client.WPFLib</RootNamespace>
    <AssemblyName>Some.Client.WPFLib</AssemblyName>
    <TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>
    <FileAlignment>512</FileAlignment>

    <!-- add this line: -->
    <ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>

    <SccProjectName>SAK</SccProjectName>
    <SccLocalPath>SAK</SccLocalPath>
    <SccAuxPath>SAK</SccAuxPath>
    <SccProvider>SAK</SccProvider>
  </ProjectGroup>
</Project>

字段状态可以包含两个值{ "_id": "bc325c2f6a99194ecab6e7bbae81b609", "_rev": "1-9745ddb21cefe3dbc8cc1f7f7bd8d11d", "uid": "bc325c2f6a99194ecab6e7bbae80eb29", "msg": "Hi there, here is a message for you!", "level": "warning", "status": "new", "created": 1467180077, "read": null } new - 我正在尝试编写一个Map / Reduce视图来返回特定用户的计数以及如何他们拥有状态为read的许多邮件以及状态为new的邮件数量。

地图功能非常简单:

read

并返回如下内容:

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

我现在正在尝试弄清楚如何编写一个可以产生这个的reduce函数:

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

如果我使用此缩减功能

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

我明白了:

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

我尝试使用| key | value +------------------------------------+------------------------------ | bc325c2f6a99194ecab6e7bbae80eb29 | ["read","read","read","new","new"] +------------------------------------+------------------------------ ,但它返回return count(values)

似乎我无法绕过头,如何处理这个问题。谁能让我走上正轨?

2 个答案:

答案 0 :(得分:2)

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

首先,我们将从map函数开始:

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

请注意,我们只发出一个密钥,而且我们没有打扰一个值。 (事实证明,在这种情况下我们不需要它)

然后,使用以下built-in reduce function

_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",{}]

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

这种方法可以很好地扩展,允许任何其他status值在没有任何代码更改的情况下工作。

答案 1 :(得分:0)

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

减少功能:

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}
+------------------------------------+------------------------------