MongoDB - 引用字段的聚合

时间:2015-04-20 15:17:03

标签: mongodb aggregation-framework

我对文档设计有疑问,以便能够有效地执行聚合。我将以文档为例:

{
   product: "Name of the product",
   description: "A new product",
   comments: [ObjectId(xxxxx), ObjectId(yyyy),....]
}

正如您所看到的,我有一个简单的文档描述了一个产品,并对其进行了一些评论。想象一下这个产品非常受欢迎,因此它包含数百万条评论。注释是一个简单的文档,包含日期,文本和最终的一些其他功能。问题是这样的产品很容易大于16MB,所以我不需要在产品中嵌入评论,而是在单独的集合中。

我现在要做的是对产品集合执行聚合,第一步可以是选择各种产品并按日期对评论进行排序。使用嵌入式文档这是一个非常简单的操作,但我怎么能用这样的设计呢?我只有注释的ObjectId而不是它们的内容。当然,我想在单个操作中执行此聚合,即我不想执行聚合的第一部分,然后查询结果并执行另一个聚合。

我不会'知道这是否足够清楚? ^^

1 个答案:

答案 0 :(得分:0)

我会这样做:创建一个临时集合,它是产品集合的精确副本,唯一的例外是comments数组中模式的更改,它将被修改为包含注释对象而不是对象id。 comment对象只有_id和date字段。以上可以一步完成:

var comments = [];
db.product.find().forEach( function (doc){
    doc.comments.forEach( function(x) {
        var obj = {"_id": x };
        var comment = db.comment.findOne(obj);
        obj["date"] = comment.date;
        comments.push(obj);
    });
    doc.comments = comments;
    db.temp.insert(doc);
});

然后,您可以针对临时集合运行聚合查询:

db.temp.aggregate([
    {
        $match: {
            // your match query
        }
    },
    {
        $unwind: "$comments"
    },    
    {
        $sort: { "comments.date": 1 } // sort the pipeline by comments date
    }
]);