【问题标题】:How to add a condition inside $lookup in MongoDb .aggregate()?如何在 MongoDb .aggregate() 的 $lookup 中添加条件?
【发布时间】:2020-09-02 15:50:47
【问题描述】:

人员集合:

{
  "_id": ObjectId("5f3258cfbaaccedaa5dd2c96"),
  "gender": "male",
  "name": {
    "title": "mr",
    "first": "victor",
    "last": "pedersen",//... more properties
} 

人物详情集合:

{
      "_id": ObjectId("5f3a91e68b1c26e68f9ed3ad"),
      "country": "India",
      "personid": ObjectId("5f3258cfbaaccedaa5dd2c96")
}

从相关人员那里获取文件以及相关人员详细信息,其中相关国家/地区的人员详细信息为“印度”

因此,如果 10 个人中只有 3 个来自印度。我应该在结果集中获得 3 个人员文档及其相关人员详细信息

查询:

 [
    {
      "$match": {
      "$or": [
         
        {
          "$expr": {
            "$eq": [
              "$gender",
              "male"
            ]
          }
        }
      ]
    }
  },
  {
    "$facet": {
      "totalCount": [
        {
          "$count": "value"
        }
      ],
      "data": [
        {
          "$project": {
            "_id": "$_id",
            "fname": "$name.first",
            "lname": "$name.last",
            "dobage": "$dob.age",
            "registeredAge": "$registered.age"                
          }
        },
        {
          "$sort": {
            "name.first": 1
          }
        } ,
        {
          "$lookup": {
            "from": "persondetails",
            "localField": "_id",
            "foreignField": "personid", // how to add where clause in this lookup?
            "as": "persondetail" 
          }
        }
      ]
    }
  }
]

编辑:

https://mongoplayground.net/p/3vBs6Frt-aK

预期结果:

[
  {
    "data": [
      {
        "_id": ObjectId("5f3258cfbaaccedaa5dd2c96"),
        "fname": "victor",
        "lname": "pedersen",
        "persondetail": [
          {
            "_id": ObjectId("5f3a91e68b1c26e68f9ed3ad"),
            "country": "India",
            "personid": ObjectId("5f3258cfbaaccedaa5dd2c96")
          }
        ]
      }],
    "totalCount": [
      {
        "value": 1
      }
    ]
  }
]

【问题讨论】:

  • 你不需要 where 子句,但在 $lookup 之后需要一个额外的 $match 阶段来过滤掉你不希望在结果中看到的人。
  • 这不会影响性能吗? @AlexBlex
  • 很可能是的。你会注意到其中的不同吗?这取决于。过早的优化被认为是一种适得其反的做法,但如果它很关键,您最好在数据集上对其进行测试。

标签: javascript node.js mongodb mongodb-query nosql


【解决方案1】:

还有第二个$lookup 语法允许您指定自定义过滤条件:

{
    "$lookup": {
        "from": "persondetails",
        "let": { person_id: "$_id" },
        "pipeline": [
            {
                $match: {
                    $expr: {
                        $and: [
                            { $eq: [ "$$person_id", "$personid" ] },
                            { $eq: [ "$country", "India" ] },
                        ]
                    }
                }
            }
        ],
        "as": "persondetail" 
    }
}

编辑: 您还需要添加 $match 以过滤掉 persondetail 为空的人,如果您希望将其包含在您的计数中,那么您需要运行 $facet 作为最后一个操作:

[
    {
        "$match": {
            "$or": [ {"$expr": { "$eq": [ "$gender", "male" ] } } ]
        }
    },
    {
        "$project": {
                "_id": "$_id",
                "fname": "$name.first",
                "lname": "$name.last",
                "dobage": "$dob.age",
                "registeredAge": "$registered.age"                
        }
    },    
    {
        "$lookup": {
            "from": "persondetails",
            "let": { person_id: "$_id" },
            "pipeline": [
                {
                    $match: {
                        $expr: {
                            $and: [
                                { $eq: [ "$$person_id", "$personid" ] },
                                { $eq: [ "$country", "India" ] },
                            ]
                        }
                    }
                }
            ],
            "as": "persondetail" 
        }
    },
    {
        $match: {
            persondetail: { $ne: [] }
        }
    },
    {
        $facet: {
            totalCount: [ { $count: "value" } ],
            data: [ { $sort: { "name.first": 1 } },  ]
        }
    }
]

Mongo Playground

【讨论】:

  • 这会过滤掉人吗?还是个人资料?
  • 这似乎不起作用。我用你的替换了我的查找,我得到了错误的输出
  • 这是@mickl 的答案,正如你所描述的那样工作
  • 它也会返回 persondetail 为空的地方@varman
  • 如果没有数据加入,那么它会给你空数组
猜你喜欢
  • 2020-01-08
  • 2020-05-11
  • 1970-01-01
  • 1970-01-01
  • 2020-09-07
  • 2019-04-04
  • 2021-02-22
  • 2021-12-13
  • 2020-11-22
相关资源
最近更新 更多