【问题标题】:$or operation for matching the same element in two different arrays$or 操作用于匹配两个不同数组中的相同元素
【发布时间】:2020-08-19 08:48:14
【问题描述】:

假设我在两个不同的文档中有两个不同的数组,即carPolicies[]paPolicies[]。显然,有policy 对象包含agent 的键。

[
  {
    "_id": "_id",
    "name": "qwe",
    "password": "pw",
    "carPolicies": [
      {
        "policy": {
          "agent": "47"
        }
      },
    ],
    "paPolicies": [
      {
        "policy": {
          "agent": "47"
        }
      },
    ]
  },


  {
    "_id": "_id",
    "name": "rty",
    "password": "wp",
    "carPolicies": [
      {
        "policy": {
          "agent": "47"
        }
      },
    ],
    "paPolicies": [
      {
        "policy": {
          "agent": "47"
        }
      },
      {
        "policy": {
          "agent": "99"
        }
      }
    ]
  }
]

如果我进行如下查询,它将仅从carPolicies[] 向我返回政策,其中agent: 47。

db.collection('users').aggregate([
    
             
    
            // get just the documents that contain an agent key where agent is  === 47 
            { $match: { 'carPolicies.policy.agent': req.params.name } },
            {
                $project: {
                    policy: {
                        $filter: {
                            input: '$carPolicies.policy',
                            as: 'police',
                            cond: { $eq: ['$$police.agent', req.params.name ]}
                        }
                    }
                }
            }
        
        ])

但是,我想修改相同的查询以检查 paPolicies[] where agent: 47 也。如何添加$or 以便能够在agent 为47 的一个查询中检查两个数组?还是有其他更适合我用例的运算符?

我的预期结果应该输出:

[
  {
    "policy": [
      {
        "agent": "47"
      }
    ]
  },
  {
    "policy": [
      {
        "agent": "47"
      }
    ]
  },
{
    "policy": [
      {
        "agent": "47"
      }
    ]
  },
  {
    "policy": [
      {
        "agent": "47"
      }
    ]
  }
]

输出中应该有 4 个策略,因为在我的示例中,只有 4 个策略具有 agent = 47,其中一个策略具有不应检索的 agent = 99。

【问题讨论】:

  • 您想在 $match 或 $filter 中添加or 条件的位置?
  • @turivishal 你是什么意思?
  • 我的意思是你想在哪里检查paPolicies 的条件?在 $match 管道还是在 $project 管道过滤器中?
  • @turivishal 最好在 $match 管道中。

标签: mongodb express aggregation-framework


【解决方案1】:

你可以试试,

  • 使用$or$match 中添加条件
  • 使用和$concatArrays在过滤器中添加paPolicies.policy作为输入
  • $unwind解构policy数组
  • $projectpolicy 转换为数组
db.collection.aggregate([
  {
    $match: {
      $or: [
        { "carPolicies.policy.agent": req.params.name },
        { "paPolicies.policy.agent": req.params.name }
      ]
    }
  },
  {
    $project: {
      policy: {
        $filter: {
          input: {
            $concatArrays: ["$carPolicies.policy", "$paPolicies.policy"]
          },
          as: "police",
          cond: { $eq: ["$$police.agent", req.params.name] }
        }
      }
    }
  },
  { $unwind: "$policy" },
  {
    $project: {
      _id: 0,
      policy: ["$policy"]
    }
  }
])

Playground

【讨论】:

  • 我检查了您的 mongo 操场链接,它没有从 paPolicies[] 检索策略,其中 agent 是 47,正如您从我的代码中看到的那样,我有一个 $filter where @ 987654334@ 具体来说是$carPolicies.policy。如果你改用$filter 怎么办?
  • 是的,这就是我问你的原因,你能从你的数据中添加你的预期结果吗
  • 当然,我会在我的问题中添加它以进行澄清。谢谢。
  • 您需要验证 _id 是否与您在集合中的 id 相同,并检查其对象 id 或集合中的字符串对象 id。
  • 是的,我有。我已经解决了这个问题。我需要在查询中明确添加 _id 是 objectId。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-28
  • 2020-11-08
  • 1970-01-01
  • 1970-01-01
  • 2018-10-21
  • 2015-10-05
相关资源
最近更新 更多