如何在mongo查询中执行嵌套查找?

时间:2019-05-17 06:11:11

标签: mongodb mongodb-query aggregation-framework

这是我的汇总查询

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 }

3 个答案:

答案 0 :(得分: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]
    }
  }}
])

答案 1 :(得分:2)

您可以通过仅依次使用$lookup$unwind并随后按 Conditional Projection 来加入任意数量的集合,无论需要什么。以下是经过充分测试的和适用的解决方案:

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 :(得分:0)

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

我解决了我的查询,在上述查找之后我不得不应用展开。