我对文档设计有疑问,以便能够有效地执行聚合。我将以文档为例:
{
product: "Name of the product",
description: "A new product",
comments: [ObjectId(xxxxx), ObjectId(yyyy),....]
}
正如您所看到的,我有一个简单的文档描述了一个产品,并对其进行了一些评论。想象一下这个产品非常受欢迎,因此它包含数百万条评论。注释是一个简单的文档,包含日期,文本和最终的一些其他功能。问题是这样的产品很容易大于16MB,所以我不需要在产品中嵌入评论,而是在单独的集合中。
我现在要做的是对产品集合执行聚合,第一步可以是选择各种产品并按日期对评论进行排序。使用嵌入式文档这是一个非常简单的操作,但我怎么能用这样的设计呢?我只有注释的ObjectId而不是它们的内容。当然,我想在单个操作中执行此聚合,即我不想执行聚合的第一部分,然后查询结果并执行另一个聚合。
我不会'知道这是否足够清楚? ^^
答案 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
}
]);