代码之家  ›  专栏  ›  技术社区  ›  scoates

couchdb视图:删除重复项*和*按时间排序

  •  7
  • scoates  · 技术社区  · 14 年前

    基于对我的回答 previous question ,我已经部分解决了我在CouchDB上遇到的一个问题。

    这导致了 a new view .

    现在,我需要做的下一件事是从此视图中删除重复项 虽然 按日期排序。

    例如,下面是我如何查询该视图:

    GET http://scoates-test.couchone.com/follow/_design/asset/_view/by_userid_following?endkey=[%22c988a29740241c7d20fc7974be05ec54%22]&startkey=[%22c988a29740241c7d20fc7974be05ec54%22,{}]&descending=true&limit=3
    

    结果是:

    HTTP 200 http://scoates-test.couchone.com/follow/_design/asset/_view/by_userid_following
    http://scoates-test.couchone.com > $_.json.rows
    [ { id: 'c988a29740241c7d20fc7974be067295'
      , key: 
         [ 'c988a29740241c7d20fc7974be05ec54'
         , '2010-11-26T17:00:00.000Z'
         , 'clementine'
         ]
      , value: 
         { _id: 'c988a29740241c7d20fc7974be062ee8'
         , owner: 'c988a29740241c7d20fc7974be05f67d'
         }
      }
    , { id: 'c988a29740241c7d20fc7974be068278'
      , key: 
     [ 'c988a29740241c7d20fc7974be05ec54'
         , '2010-11-26T15:00:00.000Z'
         , 'durian'
         ]
      , value: 
         { _id: 'c988a29740241c7d20fc7974be065115'
         , owner: 'c988a29740241c7d20fc7974be060bb4'
         }
      }
    , { id: 'c988a29740241c7d20fc7974be068026'
      , key: 
         [ 'c988a29740241c7d20fc7974be05ec54'
         , '2010-11-26T14:00:00.000Z'
         , 'clementine'
         ]
      , value: 
         { _id: 'c988a29740241c7d20fc7974be063b6d'
         , owner: 'c988a29740241c7d20fc7974be05ff71'
         }
      }
    ]
    

    如你所见,“克莱门汀”出现了两次。

    如果我更改视图以将水果/资产名称作为第二个键(而不是时间)发出,我可以更改分组深度以折叠这些项,但这并不能解决我按时间排序的要求。同样,通过上面的设置,我可以按时间排序,但是我不能将重复的资产名称折叠成单行(例如,每页10个资产)。

    不幸的是,这不是一个简单的问题。也许吧 this chat transcript 会有点帮助。

    请帮忙。恐怕我要做的事情还是不可能的。

    S

    2 回复  |  直到 14 年前
        1
  •  7
  •   Nek    14 年前

    您可以使用list函数来完成此操作。下面是一个生成一个非常简单的列表的示例,其中包含所有不带duple的owner字段。您可以轻松地修改它以生成JSON或XML或任何您想要的东西。

    把它放进资产设计文档的lists.nodupes中,如下使用: http://admin:123@127.0.0.1:5984/follow/_design/assets/_list/nodupes/by_userid_following_reduce?group=true

    function(head, req) {
        start({
              "headers": {
              "Content-Type": "text/html"
              }
             });
        var row;
        var dupes = [];
        while(row = getRow()) {
        if (dupes.indexOf(row.key[2]) == -1) {
            dupes.push(row.key[2]);
            send(row.value[0].owner+"<br>");
        }
        } 
    }
    
        2
  •  2
  •   J Chris A    14 年前

    按一个字段排序,在另一个字段上进行uniquing并不是基本的map reduce所能做的。它所能做的就是对数据进行排序,并将reduce汇总应用于动态关键范围。

    要查找每种水果的最新条目,您需要为每种水果查询一次。

    有一些方法可以做到这一点,有点理智。

    您需要一个带有键的视图,如[水果类型,日期],然后您可以这样查询:

    for fruit in fruits
      GET /db/_design/foo/_view/bar?startkey=["apples"]&limit=1&descending=true
    

    这将为您提供每个水果的最新条目。

    列表操作可以用来完成这个操作,它只会从每个水果块中反射第一行。只要每个水果都有少量的入口,这就足够有效了。一旦每个水果都有许多条目,您将丢弃的数据比回送的要多,因此当您到达一个大的数据集时,多查询方法实际上比列表方法具有更好的伸缩性。幸运的是,它们都可以在同一个视图索引上工作,所以当您必须切换时,这不会有什么大不了的。