【问题标题】:How to make aggregate + populate in Mongoose如何在猫鼬中进行聚合+填充
【发布时间】:2018-01-30 01:29:07
【问题描述】:

感谢您的帮助。我正在使用 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 }
}));

重要的是,我有兴趣填充 MyModelcategory 字段,而不是 other 字段。

假设CategoryMyModel 有某些格式良好的记录。请求:

MyModel.aggregate([
  {
    $group : {
      _id : '$_id',
      times: { $sum: '$times_count' }
    }
  },
  {
    $limit: 5
  }
]).limit(5).exec().then((data) => {
  console.log(data);
}).catch((err) => {
  console.error(err);
});

data 正确,有 5 条记录,但不包括 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);和它们看起来正确的操作,包括最后一个操作aggregate,但是数据是空的...

我不知道我解释得好不好。显然,有些事情我并不完全理解。提前致谢。

【问题讨论】:

    标签: node.js mongodb express mongoose aggregate


    【解决方案1】:

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

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

    我尝试在 $ 组之后将 $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)

    【讨论】:

    • 谢谢,但不起作用。我尝试了from: 'Category'localField: 'category' 和其他组合,我在数组中包含$limit,有&没有$unwind... 总之,几十个组合。另外,为什么需要游标?我不明白。请注意,我要填充的字段是 categoryMyModel,而不是 _id。再次感谢。
    • @LuisMiguelF。啊,你说得对,应该是category。如我的示例所示,您不需要cursor()。我还会设置debug on 来查看任何查询。使用类别架构编辑您的问题。您是否也在运行 MongoDB v3.2 或更高版本?
    • 对不起@Mikey,光标是我的错,我在这个测试中使用 Mockgoose 而不是 Mongoose(虽然我不知道为什么 Mockgoose 需要光标)。现在,我只使用猫鼬,我将编辑我的问题。仍然无法正常工作... :(
    • @LuisMiguelF。检查我的编辑。我相信您需要有一个 category 字段,然后才能将其加入另一个集合。
    • 哇!通过您的编辑,并将“类别”替换为“类别”(小写),它可以工作!非常感谢@Mikey
    猜你喜欢
    • 2019-08-29
    • 2015-09-15
    • 2017-01-23
    • 2015-12-23
    • 2016-12-19
    • 1970-01-01
    • 2017-05-06
    • 2017-06-06
    • 2016-06-11
    相关资源
    最近更新 更多