Map Reduce for MongoDB



我有一个集合,其中每个对象都包含用户的详细信息以及用户对特定产品的评论,这些评论在下面给出

{
"_id" : ObjectId("51efcbc8786df13540e46887"),
"value": {
    "UserDetails" : [
                        [
                            {
                                "country" : "CA",
                                "gender" : "M",
                                "age" : "18",
                                "userIdtemp" : ObjectId("51efcbc8786df13540e46887")
                            }
                        ]
                    ],
    "comments" :    [
                        {
                            "commentId" : ObjectId("51efcc41786df13540e46891"),
                            "comment" : "Hey, what's up?",
                            "created" : ISODate("2013-07-24T12:44:49.400Z"),
                            "productId" : ObjectId("51efcbd4786df13540e4688c"),
                            "userId" : ObjectId("51efcbc8786df13540e46887")
                        },
                        {
                            "commentId" : ObjectId("51efcc43786df13540e46893"),
                            "comment" : "Cool",
                            "created" : ISODate("2013-07-24T12:44:51.004Z"),
                            "productId" : ObjectId("51efcbd2786df13540e4688b"),
                            "userId" : ObjectId("51efcbc8786df13540e46887")
                        }
                    ]
    }
}
{
"_id" : ObjectId("51efcbc8786df13540e46888"),
"value" : {
     "UserDetails" : [
                        [
                            {
                               "country" : "US",
                               "gender" : "M",
                               "age" : "25",
                               "userIdtemp" : ObjectId("51efcbc8786df13540e46888")
                            }
                        ]
                ],
     "comments" : [
                    {
                        "commentId" : ObjectId("51efcc41786df13540e46892"),
                        "comment" : "Not much",
                        "created" : ISODate("2013-07-24T12:44:49.475Z"),
                        "productId" : ObjectId("51efcbd4786df13540e4688c"),
                        "userId" : ObjectId("51efcbc8786df13540e46888")
                    }
                ]
}
}
{
    "_id" : ObjectId("51efcbc8786df13540e46889"),
    "value" : {
            "UserDetails" : [
                    {
                            "country" : "US",
                            "gender" : "F",
                            "age" : "13",
                            "userIdtemp" : ObjectId("51efcbc8786df13540e46889")
                    }
            ]
    }
}

我必须单独提取注释和用户详细信息,密钥为productId,所以我已经写了类似于以下的地图

mapCommentsFrom = function(){
if("comments" in this.value)
{
    for(var idx = 0;idx<this.value.comments.length;idx++){
        var key = this.value.comments[idx].productId;
        var value = [{
            commentId: this.value.comments[idx].commentId,
            comment:this.value.comments[idx].comment,
            created:this.value.comments[idx].created,
            productId:this.value.comments[idx].productId,
            userId:this.value.comments[idx].userId,
            country:this.value.UserDetails[0][0].country,
            gender:this.value.UserDetails[0][0].gender,
            age : this.value.UserDetails[0][0].age
        }]
    }
}
emit(key,value);
}
reduceFrom = function(k,values){
return values;
}

但是当评论的数量超过一条时,我只得到最后一条评论,以及用户详细信息和其他人的密钥以及值。像这样的

{ "_id" : null, "value" : null }
{
    "_id" : ObjectId("51efcbd2786df13540e4688b"),
    "value" : [
            {
                    "length" : 2,
                    "commentId" : ObjectId("51efcc43786df13540e46893"),
                    "comment" : "Cool",
                    "created" : ISODate("2013-07-24T12:44:51.004Z"),
                    "productId" : ObjectId("51efcbd2786df13540e4688b"),
                    "userId" : ObjectId("51efcbc8786df13540e46887"),
                    "country" : "CA",
                    "gender" : "M",
                    "age" : "18"
            }
    ]
}
{
    "_id" : ObjectId("51efcbd4786df13540e4688c"),
    "value" : [
            {
                    "length" : 1,
                    "commentId" : ObjectId("51efcc41786df13540e46892"),
                    "comment" : "Not much",
                    "created" : ISODate("2013-07-24T12:44:49.475Z"),
                    "productId" : ObjectId("51efcbd4786df13540e4688c"),
                    "userId" : ObjectId("51efcbc8786df13540e46888"),
                    "country" : "US",
                    "gender" : "M",
                    "age" : "25"
            }
    ]
}

有人能帮我弄清楚我缺了什么吗?

感谢您提前提供帮助

由于声誉原因,我无法添加评论。但是您是否考虑过使用聚合框架。

$unwind操作符将非常容易地返回一组子文档,而且它比使用map/reduce更快。

我不确定它是否能满足你的需求,但可能会有所帮助。

看看,http://docs.mongodb.org/manual/reference/aggregation/unwind/

这是因为您没有在map函数中发出它们。在for循环中移动emit函数。

mapCommentsFrom = function(){
if("comments" in this.value){
for(var idx = 0;idx<this.value.comments.length;idx++){
    var key = this.value.comments[idx].productId;
    var value = {
        commentId: this.value.comments[idx].commentId,
        comment:this.value.comments[idx].comment,
        created:this.value.comments[idx].created,
        productId:this.value.comments[idx].productId,
        userId:this.value.comments[idx].userId,
        country:this.value.UserDetails[0][0].country,
        gender:this.value.UserDetails[0][0].gender,
        age : this.value.UserDetails[0][0].age
    }
    emit(key,value);
}
}
}

然后,您可能还需要将reduce函数重写为类似的内容

reduceFrom = function(k,valueArray){
var returnData = { values : [] } ;
for(var i=0;i<valueArray.length;i++)
    returnData.values.push(valueArray[i]);
return returnData;

}

通过far,最简单的方法就是使用聚合框架。聚合框架允许您对数据执行运算符,有用于执行查询的$match(如find())和其他各种运算符。有关详细信息,请参阅:http://docs.mongodb.org/manual/core/aggregation/

聚合框架还有一个$unwind函数,它可以完全执行您想要的操作。你使用它就像:

db.collection.aggregate( [
    { $unwind: '$value.comments' },
    { $project: {
        _id: '$value.comments.productId',
        value: 1
    } }
] );

在您的样本文档上,这会返回:

{
    "result" : [
        {
            "_id" : ObjectId("51efcbd4786df13540e4688c"),
            "value" : {
                "UserDetails" : [
                    [
                        {
                            "country" : "CA",
                            "gender" : "M",
                            "age" : "18",
                            "userIdtemp" : ObjectId("51efcbc8786df13540e46887")
                        }
                    ]
                ],
                "comments" : {
                    "commentId" : ObjectId("51efcc41786df13540e46891"),
                    "comment" : "Hey, what's up?",
                    "created" : ISODate("2013-07-24T12:44:49.400Z"),
                    "productId" : ObjectId("51efcbd4786df13540e4688c"),
                    "userId" : ObjectId("51efcbc8786df13540e46887")
                }
            }
        },
        {
            "_id" : ObjectId("51efcbd2786df13540e4688b"),
            "value" : {
                "UserDetails" : [
                    [
                        {
                            "country" : "CA",
                            "gender" : "M",
                            "age" : "18",
                            "userIdtemp" : ObjectId("51efcbc8786df13540e46887")
                        }
                    ]
                ],
                "comments" : {
                    "commentId" : ObjectId("51efcc43786df13540e46893"),
                    "comment" : "Cool",
                    "created" : ISODate("2013-07-24T12:44:51.004Z"),
                    "productId" : ObjectId("51efcbd2786df13540e4688b"),
                    "userId" : ObjectId("51efcbc8786df13540e46887")
                }
            }
        },
        {
            "_id" : ObjectId("51efcbd4786df13540e4688c"),
            "value" : {
                "UserDetails" : [
                    [
                        {
                            "country" : "US",
                            "gender" : "M",
                            "age" : "25",
                            "userIdtemp" : ObjectId("51efcbc8786df13540e46888")
                        }
                    ]
                ],
                "comments" : {
                    "commentId" : ObjectId("51efcc41786df13540e46892"),
                    "comment" : "Not much",
                    "created" : ISODate("2013-07-24T12:44:49.475Z"),
                    "productId" : ObjectId("51efcbd4786df13540e4688c"),
                    "userId" : ObjectId("51efcbc8786df13540e46888")
                }
            }
        }
    ],
    "ok" : 1
}

相关内容

  • 没有找到相关文章

最新更新