如何在Mongoose中进行聚合+填充

时间:2017-08-21 22:02:42

标签: node.js mongodb express mongoose aggregate

我感谢一些帮助。我使用mongoose(v4.10.5)使用express和mongodb(v3.4.4)进行api休息。我需要做一个聚合操作,但我不处理它。我给你看一些代码。模型(它有更多的属性,但我把它简单化了):

const CategoryModel = mongoose.model('Category', new Schema({
    slug: { type: String, unique: true, lowercase: true, index: true },
    description: String
}));

const MyModel = mongoose.model('MyModel', new Schema({
    category: { type: Schema.Types.ObjectId, ref: 'Category' },
    other: [{ type: Schema.Types.ObjectId, ref: 'Other' }], 
    times_count: { type: Number, default: 0 }
}));

重要的是,我有兴趣填充category的{​​{1}}字段,而不是MyModel字段。

假设otherCategory已形成良好的记录。请求:

MyModel

MyModel.aggregate([ { $group : { _id : '$_id', times: { $sum: '$times_count' } } }, { $limit: 5 } ]).limit(5).exec().then((data) => { console.log(data); }).catch((err) => { console.error(err); }); 是正确的,有5条记录,但不包括data。现在,我尝试:

category

现在MyModel.aggregate([ { $group : { _id : '$_id', times: { $sum: '$times_count' } } }, { $limit: 5 }, { $lookup: { from: 'Category', // I tried with 'Categories' and 'categories' localField: 'category', foreignField: '_id', as: 'category' } }, { $unwind: '$category' } ]).limit(5).exec().then((data) => { console.log(data); }).catch((err) => { console.error(err); }); 为空。我设置了data以及他们看起来正确的操作,包括最后一个操作mongoose.set('debug', true);,但数据是空的......

我不知道我是否解释得很好。显然有一些我不完全理解的东西。提前谢谢。

1 个答案:

答案 0 :(得分:2)

  

我在objs中获得了所需的记录,问题是我只带有_id和times属性,我需要填充类别。

这是正确的,因为你没有明确地添加阶段加入其他集合。

  

我尝试在$ group之后将$ project添加到聚合中,但没有。

简单来说,$project用于包含和排除使用一个集合的新字段,而不是加入。

您正在寻找$lookup用于加入一个集合与另一个集合。当您加入新集合时,每个文档都将有一个新的数组字段,其中包含来自其他集合的“已加入”文档。

在您的情况下,您的新数组字段将包含来自其他集合的一个文档,因此您可能也希望$unwind

MyModel.aggregate([
    {
        $group : {
            _id : '$_id',
            times: { $sum: '$times_count' },
            category: { $first: '$category' }
        }
    },
    /*
    {
        $limit: 5
    },
    */
    {
        $lookup: {
            from: 'Categories',
            localField: 'category',
            foreignField: '_id',
            as: 'category'
        }
    },
    {
        $unwind: '$category'
    }
]).exec(...);

就您的初始问题而言,请尝试取消注释上面的第二阶段,而不是在第一个示例中使用limit(5)