Mongoose:找到所有文档,其中数组中嵌套的子文档的_Id与userId匹配

时间:2017-09-27 01:56:27

标签: mongodb mongoose mongoose-populate

缩写架构:

const ThingSchema = new mongoose.Schema({
  _id: {
    type: String,
  },
  widgets: [{
    user: {
      type: Schema.Types.ObjectId,
      ref: 'user',
    },
    lastViewedAt: {
      type: Date,
    },
  }],
}, { _id: false });

鉴于userId,您如何获得用户所属的所有Things user是深层嵌套对象数组中的子文档?

我已经介绍了在类似的“查找对象数组”问题的答案中找到的几种方法,这些问题表明.where$in.populate match无法得到的不只是Things或nada的完整,未经过滤的集合。我欢迎反馈,为什么我上面尝试的特定方法对于我所追求的过滤结果的最终目标来说是一个糟糕/好的选择。

更新

我使用的部分解决方案aggregate。首先,我必须$unwind widgets数组。在由$unwind生成的结果集合中,然后$match编辑了用户的_id

与其他查询不同,ObjectId调用mongoose does not autocast _ids进入mongo aggregate的问题。我必须使用_id明确转换mongoose.Types.ObjectId()字符串。

const things = await Thing.aggregate([
  { $unwind: '$widgets' },
  { $match: { 'widgets._id': mongoose.Types.ObjectId(userId) } }
]);

这里唯一的问题是,在展开 widgets数组的过程中,我丢失了完整的用户集合,只获得了我正在搜索的ID的单个用户现在在那个集合中。我现在需要做一些事情,比如抓住Thing的ID并再次运行一个查询和.populate()用户。

我在$filter

的特别详细的情况下得到了类似的结果
const things = await Thing.aggregate([
  { "$match": {
    "widgets._id": { "$in": [ mongoose.Types.ObjectId(userId) ] }
  }},
  { "$project": {
    "widgets": {
      "$filter": {
        "input": "$widgets",
        "as": "user",
        "cond": { "$or": [{ "$eq": [ "$$user._id", mongoose.Types.ObjectId(userId) ] }] },
      }
    }
  }}
]);

0 个答案:

没有答案