簡體   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