【问题标题】:Agregate query with lookup and restriction condition in MongoDb在 MongoDb 中使用查找和限制条件聚合查询
【发布时间】:2020-04-09 11:26:26
【问题描述】:

我有一个收藏myCollection

{
   name : String,
   members: [{status : Number, memberId : {type: Schema.Types.ObjectId, ref: 'members'}]
}

有了这些数据:

"_id" : ObjectId("5e8b0bac041a913bc608d69d")
  "members" : [ 
        {
            "status" : 4,
            "_id" : ObjectId("5e8b0bac041a913bc608d69e"),
            "memberId" : ObjectId("5e7dbf5b257e6b18a62f2da9"),
            "date" : ISODate("2020-04-06T10:59:56.997Z")
        }, 
        {
            "status" : 1,
            "_id" : ObjectId("5e8b0bf2041a913bc608d6a3"),
            "memberId" : ObjectId("5e7e2f048f80b46d786bfd67"),
            "date" : ISODate("2020-04-06T11:01:06.463Z")
        }
    ],

和一个集合成员

{
  firstname : String
  lastname  : String
} 

有了这个数据:

  [{
        "_id" : ObjectId("5e7dbf5b257e6b18a62f2da9"),
        "firstname" : "raed",
        "lastname" : "besbes"
    }, 
    {
        "_id" : ObjectId("5e7e2f048f80b46d786bfd67"),
        "firstname" : "sarra",
        "lastname" : "besbes"
    }]

我使用聚合和 $lookup 进行查询,以填充数据,但我想限制返回 仅状态 1 的数据,这是我的查询和结果。 如何获取仅返回状态 1 成员的数据?谢谢。

查询

db.getCollection('myCollection').aggregate([
        { $match: { _id: ObjectId("5e8b0bac041a913bc608d69d")}},
       {
            "$lookup": {
                "from": "members",
                "localField": "members.memberId",
                "foreignField": "_id",
                "as": "Members"
            }
        },
        {
            $project: {
                "Members.firstname" : 1,
                "Members.lastname" : 1,
                "Members._id" : 1,
                },

        }


    ])

结果

{
    "_id" : ObjectId("5e8b0bac041a913bc608d69d"),
    "Members" : [ 
        {
            "_id" : ObjectId("5e7dbf5b257e6b18a62f2da9"),
            "firstname" : "raed",
            "lastname" : "besbes"
        }, 
        {
            "_id" : ObjectId("5e7e2f048f80b46d786bfd67"),
            "firstname" : "sarra",
            "lastname" : "besbes"
        }
    ]
}

【问题讨论】:

    标签: mongodb aggregation-framework lookup


    【解决方案1】:

    选项 1

    $lookup之前过滤members

    db.myCollection.aggregate([
      {
        $match: {
          _id: ObjectId("5e8b0bac041a913bc608d69d")
        }
      },
      {
        $addFields: {
          members: {
            $filter: {
              input: "$members",
              cond: {
                $eq: [
                  "$$this.status",
                  1
                ]
              }
            }
          }
        }
      },
      {
        "$lookup": {
          "from": "members",
          "localField": "members.memberId",
          "foreignField": "_id",
          "as": "Members"
        }
      },
      {
        $project: {
          "Members.firstname": 1,
          "Members.lastname": 1,
          "Members._id": 1
        }
      }
    ])
    

    MongoPlayground

    选项 2

    (类似于1)我们将member数组展平,只过滤status = 1,然后执行$lookup

    db.myCollection.aggregate([
      {
        $match: {
          _id: ObjectId("5e8b0bac041a913bc608d69d")
        }
      },
      {
        "$unwind": "$members"
      },
      {
        $match: {
          "members.status": 1
        }
      },
      {
        "$lookup": {
          "from": "members",
          "localField": "members.memberId",
          "foreignField": "_id",
          "as": "Members"
        }
      },
      {
        "$unwind": "$Members"
      },
      {
        $group: {
          _id: "$_id",
          Members: {
            $push: "$Members"
          }
        }
      }
    ])
    

    MongoPlayground

    选项 3

    我们可以根据member 数组的过滤值对Member 数组应用过滤器。

    db.myCollection.aggregate([
      {
        $match: {
          _id: ObjectId("5e8b0bac041a913bc608d69d")
        }
      },
      {
        "$lookup": {
          "from": "members",
          "localField": "members.memberId",
          "foreignField": "_id",
          "as": "Members"
        }
      },
      {
        $project: {
          Members: {
            $filter: {
              input: "$Members",
              cond: {
                $in: [
                  "$$this._id",
                  {
                    $let: {
                      vars: {
                        input: {
                          $filter: {
                            input: "$members",
                            cond: {
                              $eq: [
                                "$$this.status",
                                1
                              ]
                            }
                          }
                        }
                      },
                      in: "$$input.memberId"
                    }
                  }
                ]
              }
            }
          }
        }
      }
    ])
    

    MongoPlayground

    【讨论】:

      猜你喜欢
      • 2017-11-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-20
      • 1970-01-01
      • 1970-01-01
      • 2020-07-27
      • 1970-01-01
      相关资源
      最近更新 更多