在猫鼬中查找条件

时间:2020-12-31 08:12:26

标签: mongodb mongoose aggregation-framework

我有两个系列。文章和书签。

文章

{
    _id: "5faa889ade5e0a6326a873d3",
    name: "article 1"
},
{
    _id: "5faa889ade5e0a6326a873d",
    name: "article 2"
}

书签

{
    _id: "5faa889ade5e0a6326a873d1",
    user_id: "5fc7b50da483a66a86aa7e9e",
    model_id: "5faa889ade5e0a6326a873d3"
}

我想加入带有书签的文章。如果用户为文章添加了书签。 我试过的

const aggregate = await Articles.aggregate([{
        $lookup: {
            from: "categories",  
            localField: "category_id",
            foreignField: "_id",
            as: "category_id"
        }
    },
    {

        $lookup: {
            from: "bookmarks",  
            localField: "_id",
            foreignField: "model_id",
            as: "bookmarks"
        }
    }
]);

但它不仅会为登录的用户书签提供文章的所有书签。那么如何添加条件。

{ "user_id": objectId(req.user._id) } // logged user id

2 个答案:

答案 0 :(得分:1)

您可以使用 $lookup with pipeline 从 MongoDB v3.6 开始

  • 让 localField _id 作为 model_id 变量传递,您可以使用 $$ 引用在查找管道内使用该字段,
  • 用于放置 $match 阶段并匹配您所需条件和 user_id 条件的管道
  {
    $lookup: {
      from: "bookmarks",
      let: { model_id: "$_id" },
      pipeline: [
        {
          $match: {
            $expr: { $eq: ["$$model_id", "$model_id"] },
            user_id: objectId(req.user._id)
          }
        }
      ],
      as: "bookmarks"
    }
  }

MongoDB v3.4 的其他选项,

  • $filter 迭代 bookmarks 的循环并根据条件获取过滤的书签
  {
    $lookup: {
      from: "bookmarks",
      localField: "_id",
      foreignField: "model_id",
      as: "bookmarks"
    }
  },
  {
    $addFields: {
      bookmarks: {
        $filter: {
          input: "$bookmarks",
          cond: { $eq: ["$$this.user_id", objectId(req.user._id)] }
        }
      }
    }
  }

答案 1 :(得分:1)

您可以在 $lookup 内嵌套管道,

db.articles.aggregate([
  {
    $lookup: {
      from: "bookmarks",
      let: {
        article_id: "$_id"
      },
      pipeline: [
        {
          $match: {
            $expr: {
              $and: [
                {
                  $eq: [
                    "$model_id",
                    "$$article_id"
                  ]
                },
                {
                  $eq: [
                    "$user_id",
                    "5fc7b50da483a66a86aa7e9a"
                  ]
                }
              ]
            }
          }
        }
      ],
      as: "bookmarks"
    }
  }
])

这是一个有效的 playground