【问题标题】:Match a nested object field present in an array in lookup aggregation匹配查找聚合中存在于数组中的嵌套对象字段
【发布时间】:2021-02-08 00:53:08
【问题描述】:

我有两个集合ProjectsUsers

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

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

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

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

我正在尝试使用查找聚合将UsersProjects 连接起来。

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.js mongodb mongoose aggregation-framework


【解决方案1】:

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

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

Playground

警告

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

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"
    }
  }
])

Playground

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-01-24
    • 2018-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-13
    • 2020-12-18
    • 1970-01-01
    相关资源
    最近更新 更多