是否有可能映射/减少一组"评级"进入"关系"在couchdb / cloudant?

时间:2014-08-17 03:02:08

标签: mapreduce couchdb cloudant

我有"评分"记录用户对某个项目的评级的文档,如下所示:

accountID: a1, itemID: i1, rating: 1
accountID: a2, itemID: i1, rating: 1
accountID: a3, itemID: i1, rating: 1
accountID: a1, itemID: i2, rating: 1
accountID: a2, itemID: i3, rating: 1

我想创建一个视图,显示哪些用户评价了相同的项目,以及多少次。根据上述数据,我们看到a1,a2和a3对同一项目i1进行了评级,而i2和i3仅对其进行了单独评级。结果集应如下所示:

accountID1: a1, accountID2: a2, numMatches: 1
accountID1: a1, accountID2: a3, numMatches: 1
accountID1: a2, accountID2: a3, numMatches: 1

这表明a1和a2都评价了相同的项目一次(i1),a1和a3以及a2和a3(都是i1)。其他项目被忽略,因为只有一个用户对它们进行了评分。

是否可以在couchdb / cloudant中使用map / reduce实现此转换?或者,我是否必须通过提取给定项目的所有评级并运行每个帐户来进行客户端计算?

1 个答案:

答案 0 :(得分:0)

您可以解决此问题的一种方法是对itemId + userId建立索引,将评级作为值发出,然后使用_stats获取您想要的任何信息。这是您的设计文档:

{
  _id: "_design/count_shared_reviews",
  views: {
    "count_shared_reviews": {
      map: function(doc) {
        emit([doc.itemID, doc.accountID], doc.rating);
      }.toString(),
      reduce: "_stats"
    }
  }
}

然后,例如你可以做http://localhost:5984/testdb1/_design/count_shared_ratings/_view/count_shared_ratings?reduce=true&group=true&group_level=1,它将按级别1(即项目ID)分组,给你:

{"rows":[
  {"key":["i1"],"value":{"sum":3,"count":3,"min":1,"max":1,"sumsqr":3}},
  {"key":["i2"],"value":{"sum":1,"count":1,"min":1,"max":1,"sumsqr":1}},
  {"key":["i3"],"value":{"sum":1,"count":1,"min":1,"max":1,"sumsqr":1}}
]}

您还可以按所有内容进行分组,在这种情况下,您将获得每个用户的每个项目摘要(http://localhost:5984/testdb1/_design/count_shared_ratings/_view/count_shared_ratings?reduce=true&group=true):

{"rows":[
  {"key":["i1","a1"],"value":{"sum":1,"count":1,"min":1,"max":1,"sumsqr":1}},
  {"key":["i1","a2"],"value":{"sum":1,"count":1,"min":1,"max":1,"sumsqr":1}},
  {"key":["i1","a3"],"value":{"sum":1,"count":1,"min":1,"max":1,"sumsqr":1}},
  {"key":["i2","a1"],"value":{"sum":1,"count":1,"min":1,"max":1,"sumsqr":1}},
  {"key":["i3","a2"],"value":{"sum":1,"count":1,"min":1,"max":1,"sumsqr":1}}
]}

这有意义吗?