如何在不使用 unwind 的情况下匹配 mongodb 中的 _id 和特定数组元素

how to match _id and perticular array element in mongodb without using unwind

用户数据包括:

"_id" : 4
"username" : "smith"
likedVideos :[
           "videoId" : 10
           "title" : "something"
           "speaker" : "something"
           "description" : "something"
         ]

我有一个包含 userId 的集合和一系列喜欢的视频 lists.liked videos(Array) 包括 videoId 和视频详细信息。所以我需要检查用户是否已经喜欢这个视频。那么我如何在不使用 unwind 的情况下匹配集合中的 userId 和 videoId?

我试过了:

  1. const data = await userModel.findOne({ _id : userId,likedVideos: { $elemMatch: { videoId : videoId } } }) 但它 returns 该用户的所有数据。

  2. const alreadyLiked = await userModel.aggregate([ { $匹配:{ '_id':用户ID, 'likedVideos.videoId' : 视频编号, }, }, ]);

这也没有按预期工作。

我需要一个完美的解决方案来匹配数组中的元素而不使用展开(我的老板说展开是一项代价高昂的操作,它会影响应用程序的性能)。你能帮我解决这个问题吗?

您的两个查询都有效。 它将 return 所有与您的查询匹配的用户。您正在匹配特定用户和电影。因此,如果用户被 returned,则表示该用户已经喜欢该视频。

不过,当您有多个条件要应用于一个对象时,$elemMatch 很有用。所以最好将你的第二个解决方案与

一起使用
{
  "_id": userId,
  "likedVideos.videoId": videoId
}

如果只想保留 likedVideos 中的给定元素,可以在聚合中使用 $filter

例如

db.collection.aggregate([
  {
    $match: {
      "_id": 1
    }
  },
  {
    $project: {
      list: {
        $filter: {
          input: "$likedVideos",
          as: "item",
          cond: {
            $eq: [
              "$$item.videoId",
              1
            ]
          }
        }
      }
    }
  }
])

它只会 return likedVideosid=1

中的电影

试一试here

过滤子数组中元素的最佳方法是使用 $match$project 的聚合。

示例:

[{
  $match: { 
    _id: 'userId',
    likedVideos.videoId: 'videoId'
  }
}, {
  $project: {
    'likedVideos': {
      $filter: {
          input: '$likedVideos',
          as: 'item',
          cond: 
             {$eq: ["$$item.videoId","videoId"]}
      }
    }
  }
}]