【问题标题】:$lookup when foreignField is array当foreignField是数组时的$lookup
【发布时间】:2019-06-29 13:45:04
【问题描述】:

我有 2 个收藏,第一个存储每个用户观看的动漫、他们的状态等:

const listSchema = mongoose.Schema({
  user: {
    type: Schema.Types.ObjectId,
    ref: 'user'
  },
  animes: [{
    _id: false,
    anime: {
      type: Schema.Types.ObjectId,
      ref: 'anime',
      unique: true
    },
    status: String,
    episodes: Number,
    rating: Number
  }]
});

第二个存储所有动漫和相关信息。 我想显示第二个集合,但添加从登录用户列表中填充的 statusepisodes 字段。

我尝试了以下方法:

Anime.aggregate([
    {
      $lookup: {
        'from': 'lists',
        localField: '_id',
        foreignField: 'animes.anime',
        'as': 'name'
      },
    },
    {
      $unwind: '$animes'
    },
    {
      $project:{
        status:'$lists.animes.status'
      }
    }
  ]
)

但它返回一个空数组。 我也不知道如何通过userId 进行过滤,看看_id 在国外集合中的情况。

【问题讨论】:

  • 因为您的foreignField 是一个数组或对象,所以您无法获取匹配的文档
  • 我认为$unwind 会解决这个问题。请问有什么解决方法吗?

标签: mongodb mongoose mongodb-query aggregation-framework


【解决方案1】:

你可以使用下面的聚合

{ "$lookup": {
  "from": "lists",
  "let": { "id": "$_id" },
  "pipeline": [
    { "$match": { "$expr": { "$in": ["$$id", "$animes.anime"] }}},
    { "$unwind": "$animes" },
    { "$match": { "$expr": { "$eq": ["$animes.anime", "$$id"] }}}
  ],
  "as": "name"
}}

【讨论】:

  • 谢谢!起初无法弄清楚let 的用途。它有效,我只是用"$match": {"$expr": {"$eq": ["$user", mongoose.Types.ObjectId(req.userId)]}} 替换了第二个$match 来选择用户,现在它适用于所有用户。谢谢
  • let 变量中的变量可以在$lookup 中访问,否则你不能。就像上面的查询一样,我们可以使用$$ 访问管道内的_id。看看
  • 所以let 允许您定义外部字段,然后使用$$$ 访问它们以获得本地字段?我想我现在明白了,谢谢。
猜你喜欢
  • 2018-11-27
  • 1970-01-01
  • 2019-02-10
  • 1970-01-01
  • 2020-02-20
  • 2016-06-01
  • 1970-01-01
  • 2021-06-19
  • 1970-01-01
相关资源
最近更新 更多