查询嵌套的子文档数组

Query nested arrays of subdocuments

编辑:查询不应使用“&”字符。那些或用于更新。

答案:由 Gibbs 提供

correct: 
const result : any = await mongoose.model('Events').update(
    {
        _id: eventId,
        "groups._id": groupId,
        "groups.users._id": userId
    },

incorrect:
const result: any = await mongoose.model('Events').findOne(
    {
        _id: eventId,
        "groups._id": "5f270416e7964b20d6f8953e",
        "groups.$.users": { _id: '5f270877b4942d2528885dbd' }
    })
    // OR:
    {
        _id: eventId,
        "groups._id": "5f270416e7964b20d6f8953e",
        "groups.$.users._id" : '5f270877b4942d2528885dbd',  
    })

只有前两个谓词(eventId 和分组 [$_id])它 returns 事件。但是第三次​​断了。

有人知道为什么这个 returns null(对象 ID 直接从数据库复制) 谢谢!

{
    "_id": ObjectId("5f270416e7964b20d6f8953d"),
    "lastRounds": [],
    "name": "EpicFest",
    "start": 1596392488896.0,
    "end": 1596392500896.0,
    "groups": [
      {
        "_id": ObjectId("5f270416e7964b20d6f8953e"),
        "name": "Vossius",
        "users": [
          {
            "created": 1596393590778.0,
            "sessionId": null,
            "feedBack": {
              "messagesSent": 0,
              "messagesSentLiked": 0,
              "messagesReceived": 0,
              "messagesReceivedLiked": 0,
              "userFeedbackReceived": [],
              "chatFeedbackReceived": [],
              "_id": ObjectId("5f270877b4942d2528885dbe")
            },
            "_id": ObjectId("5f270877b4942d2528885dbd"),
            "image": "someAvatr",
            "name": "hans",
            "groupId": "5f270416e7964b20d6f8953e",
            "results": []
          },
          
        ]
      },
      {
        "_id": ObjectId("5f270416e7964b20d6f8953f"),
        "users": [],
        "name": "Ignatius"
      }
    ],
    "results": [],
    "theses": [],
    "rounds": 10,
    "schedule": [],
    "__v": 4
}

Mongo Play

db.collection.find({
  _id: ObjectId("5f270416e7964b20d6f8953d"),
  "groups._id": ObjectId("5f270416e7964b20d6f8953e"),
  "groups.users._id": ObjectId("5f270877b4942d2528885dbd")
})

您尝试使用字符串 "5f270416e7964b20d6f8953e"。应该是ObjectId

您可以使用 . 表示法访问嵌套元素或 $elemMatch

使用聚合管道根据内部sub-document进行抓取。

在第一个匹配阶段,按 eventId 过滤并在内部 groupId 上执行 $elemMatch。 接下来,展开 groupgroups.user.

Post 展开你将拥有一个平面对象结构,你可以再次对其应用过滤器,现在只需在 groups.user._id 上应用匹配阶段。

const pipeline = [
    {
        $match: {
            _id: eventId,
            groups: {
                $elemMatch: mongoose.Types.ObjectId('5f270416e7964b20d6f8953e')
            }
        }
    },
    {
        $unwind: '$groups'
    },
    {
        $unwind: '$groups.users'
    },
    {
        $match: {
            '$groups.users._id': mongoose.Types.ObjectId('5f270877b4942d2528885dbd')
        }
    }
];
const result: any = await mongoose.model('Events').aggregate(pipeline).exec();