【问题标题】:How to perform nested lookup in mongo query?如何在 mongo 查询中执行嵌套查找?
【发布时间】:2019-05-18 15:45:22
【问题描述】:

这是我的聚合查询

db.user.aggregate([
  { $addFields: { user_id: { $toString: "$_id" } } },
  {
    $lookup: {
      from: "walletData",
      let: { id: "$user_id" },
      pipeline: [
        {
          $match: {
            $expr: {
              $and: [
                {
                  $eq: ["$userId", "$$id"]
                },
                {
                  $gt: ["$lastBalance", 0]
                }
              ]
            }
          }
        }
      ],
      as: "balance"
    }
  }
])

我从这个结果中得到了想要的输出,但需要在这个查询中加入另一个集合。我怎样才能做到这一点?

例如考虑这些集合:

user : {
  "_id": ObjectId("xyz")
}

walletData:{
  "userId": "xyz",
  "lastBalance": 5
}


AnotherWalletdata:{
  "userId": "xyz",
  "lastBalance": 6
}

我加入前两个表后得到结果只有当第二个表(walletData)的余额大于零时我如何加入第三个表?

预期输出:

{"id":"xyz", "walletdataBal":5, "AnotherWalletDataBal":6 }

【问题讨论】:

  • 输出应该是什么?
  • 输出应该是这样的 - { id:"xyz" , walletdataBal:5, anotherwalletdataBal:6}。现在我得到它 {id:"xyz", walletdataBal:5, anotherwalletdata:null}

标签: mongodb mongodb-query aggregation-framework


【解决方案1】:

您可以通过仅使用$lookup$unwind 一个接一个地接着使用条件投影 来加入任意数量的集合,以达到最后所需的一切。以下是经过充分测试且适用的解决方案:

db.user.aggregate([
{$lookup: {from: "walletData", localField: "_id", foreignField: "userId", as: "walletDataBal"}},
{$unwind: "$walletDataBal"},
{$lookup: {from: "anotherwalletData", localField: "_id", foreignField: "userId", as: "anotherWalletDataBal"}},
{$unwind: "$anotherWalletDataBal"},
{$project: {"id": "$_id", "_id": 0, walletDataBal: "$walletDataBal.lastBalance",
anotherWalletDataBal: {$cond: 
{if: { $gt: [ "$walletDataBal.lastBalance", 0 ] },
then: "$anotherWalletDataBal.lastBalance",
else: "$$REMOVE" }}}
]).pretty();

【讨论】:

    【解决方案2】:

    你可以再添加一个$lookup阶段来实现输出

    db.user.aggregate([
      { "$addFields": { "user_id": { "$toString": "$_id" } } },
      { "$lookup": {
        "from": "walletData",
        "let": { "id": "$user_id" },
        "pipeline": [
          { "$match": {
            "$expr": {
              "$and": [
                { "$eq": ["$userId", "$$id"] },
                { "$gt": ["$lastBalance", 0] }
              ]
            }
          }}
        ],
        "as": "balance"
      }},
      { "$lookup": {
        "from": "anotherWalletData",
        "let": { "id": "$user_id" },
        "pipeline": [
          { "$match": {
            "$expr": {
              "$and": [
                { "$eq": ["$userId", "$$id"] },
                { "$gt": ["$lastBalance", 0] }
              ]
            }
          }}
        ],
        "as": "anotherWalletData"
      }},
      { "$project": {
        "walletdataBal": { "$arrayElemAt": ["$balance.lastBalance", 0] },
        "anotherwalletdataBal": {
          "$arrayElemAt": ["$anotherWalletData.lastBalance", 0]
        }
      }}
    ])
    

    【讨论】:

    • 感谢安东尼的及时回复。但是我之前尝试过这个查询,这个查询的问题是如果“walletData”用户的余额为空,它仍然显示“Anotherwalletdata”用户的余额
    • 好的,如果walletData 余额存在,您是否只想显示anotherwalletdata 的余额?如果是,请编辑您的问题并进行解释。
    【解决方案3】:

    { $unwind: "$balance" }, { $lookup: { from: "walletData", localField: "balance.userId", foreignField: "userId", as:"anotherwalletData" }} ])

    我解决了我的查询,我必须在上述查找后应用展开。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-08-21
      • 2022-01-15
      • 2017-05-12
      • 2013-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多