首页 > 解决方案 > 匹配查找聚合中存在于数组中的嵌套对象字段

问题描述

我有两个系列ProjectsUsers.

Projects有一个包含以下内容的预算字段:1)amount和 2)currency

{
  _id: ObjectId(...),
  type: 'typeA',
  budget: {
    amount: 123,
    currency: 'USD'
  }
}

Users有一个名为的字段bids,其中包含具有字段amount和的对象列表currency

{
  _id: ObjectId(...),
  name: "User name",
  bids: [{amount: 123, currency: "USD"}, {amount: 342, currency: "INR"}]
}

我正在尝试Users使用Projects查找聚合加入。

db.Projects.aggregate([
    {
        $lookup: {
          from: "Users",
          let: { projectAmount: "$budget.amount", projectCurrency: "$budget.currency" },
          pipeline: [
            {$match: {
              $expr: {
                $and: [
                   { $eq: ["$bids.amount",   "$$projectAmount"] },
                   { $eq: ["$bids.currency", "$$projectCurrency"] }
                ]
              }
            }}
          ],
          as: "matchingBids"
    }
]);

但是,尽管用户集合中有一些匹配的对象,但我总是得到空结果。我浏览了官方文档和互联网,但没有发现任何帮助。任何帮助,将不胜感激。谢谢

标签: node.jsmongodbmongooseaggregation-framework

解决方案


尝试$in具有完整对象和数组的运算符

  • 将预算对象传入let
  • 用数组检查$in条件bids
db.Projects.aggregate([
  {
    $lookup: {
      from: "Users",
      let: { budget: "$budget" },
      pipeline: [
        {
          $match: {
            $expr: { $in: ["$$budget", "$bids"] }
          }
        }
      ],
      as: "matchingBids"
    }
  }
])

操场

警告

只有当对象中的字段顺序和对象数组应该相同时,上述方法才有效,下面的示例将不起作用!

budget: { amount: 123, currency: "USD" }
bids: [{ currency: "USD", amount: 123 }]

或者

budget: { currency: "USD", amount: 123 }
bids: [{ amount: 123, currency: "USD" }]

编辑:

经过一些解决方法后,我找到了一种方法来确保匹配确切的字段以克服上述情况,

  • $or条件与字段位置的可能性{amount, currency}{currency, amount}
db.Projects.aggregate([
  {
    $lookup: {
      from: "Users",
      let: { budget: "$budget" },
      pipeline: [
        {
          $match: {
            $expr: {
              $or: [
                {
                  $in: [
                    { amount: "$$budget.amount", currency: "$$budget.currency" },
                    "$bids"
                  ]
                },
                {
                  $in: [
                    { currency: "$$budget.currency", amount: "$$budget.amount" },
                    "$bids"
                  ]
                }
              ]
            }
          }
        }
      ],
      as: "matchingBids"
    }
  }
])

操场


推荐阅读