繁体   English   中英

Mongodb - 多个集合

[英]Mongodb - multiple collections

我在 Mongo (v5.0) 中有 3 个集合,我想使用其他集合中的值获取集合的子集。 我使用了$redact$lookup等选项,但没有得到正确的结果。 最重要的部分是数组中的数组查找。

用户

[
{ "id": "a@example.com", "region": "US"},
{ "id": "b@example.com", "region": "EU"},
{ "id": "c@example.com", "region": "EU"},
{ "id": "d@example.com", "region": "US"},
]

团体

{ 
"HR": [ "a@example.com", "c@example.com" ],
"IT": [ "b@example.com", "d@example.com" ]
}

我想从名为的第三个集合中过滤所有用户

规则

[ 
"group" : ["HR"],
"region" : ["US", "EU"]
]

所以最终结果应该是“美国或欧盟地区 HR 中的所有用户”

[
{ "id": "a@example.com", "region": "US"},
{ "id": "c@example.com", "region": "EU"},
]

请帮忙。

不确定此查询的性能如何执行,但会产生预期的结果:

  1. $lookup - 加入usersgroups集合:

    1.1。 $filter - 从结果1.1.1中过滤文档,其中k不是_id (仅搜索“HR”和“IT”)并且v数组通过$in包含user_id

    1.1.1。 $objectToArray - 将键值对转换为文档。

    1.2. $unwind - 将groups数组解构为文档。

    1.3. $replaceWith - 用groups字段替换输入文档。

  2. $lookup - 加入rules集合:

    2.1。 $filter - 过滤文档:

    2.1.1。 $size & $setIntersection - 至少有 1 个元素与groups_dept (又名groups.k )变量与groups相交。

    2.1.2. $in - region变量在 ( $in ) region数组中。

  3. $match - 使用rules过滤文档不是空数组。 (意味着满足rules标准。

  4. $unset - 删除rulesgroups字段。

db.users.aggregate([
  {
    $lookup: {
      from: "groups",
      let: {
        user_id: "$id"
      },
      pipeline: [
        {
          $project: {
            groups: {
              $filter: {
                input: {
                  $objectToArray: "$$ROOT"
                },
                cond: {
                  $and: [
                    {
                      $not: {
                        $eq: [
                          "_id",
                          "$$this.k"
                        ]
                      }
                    },
                    {
                      $in: [
                        "$$user_id",
                        "$$this.v"
                      ]
                    }
                  ]
                }
              }
            }
          }
        },
        {
          $unwind: "$groups"
        },
        {
          $replaceWith: "$groups"
        }
      ],
      as: "groups"
    }
  },
  {
    $lookup: {
      from: "rules",
      let: {
        groups_dept: "$groups.k",
        region: "$region"
      },
      pipeline: [
        {
          $match: {
            $expr: {
              $and: [
                {
                  $gt: [
                    {
                      $size: {
                        $setIntersection: [
                          "$$groups_dept",
                          "$group"
                        ]
                      }
                    },
                    0
                  ]
                },
                {
                  $in: [
                    "$$region",
                    "$region"
                  ]
                }
              ]
            }
          }
        }
      ],
      as: "rules"
    }
  },
  {
    $match: {
      rules: {
        $not: {
          $eq: []
        }
      }
    }
  },
  {
    $unset: [
      "rules",
      "groups"
    ]
  }
])

示例 Mongo Playground

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM