【问题标题】:Some kind of a join-aggregation query in MongoDBMongoDB 中的某种连接聚合查询
【发布时间】:2019-10-13 15:06:06
【问题描述】:

在我的数据库中,我有两个集合:

Subjects Collection
 - id : ObjectID(own)
 - subjectCreator : ObjectID(of a user)
 - groups : Array
            [
                 ObjectID(of a group),
                 ObjectID(of a group),
                 ....more
            ]
 - media : Array
            [
                 { 
                     id : ObjectID(of media)
                     mediaUploader: ObjectID(of user)
                     other properties that not important
                 },
                 { 
                     id : ObjectID(of media)
                     mediaUploader: ObjectID(of user)
                     other properties that not important
                 },

            ]

还有一个 Groups 集合

Groups Collection
 - id : ObjectID(own)
 - groupName: string
 - groupAdmin: ObjectID(of user)
 - members: Array
            [
                 ObjectID(of a user),
                 ObjectID(of a user),
                 ....more
            ]

我想做的是, 当给定用户 ID (ObjectID) 获取用户可以看到的所有主题的数组。

用户可以通过两个标准查看主题:

  1. 如果他们是主题创建者

  2. 如果他们是主题包含在groups 字段中的组的成员

我知道这是两个查询之间的一种聚合, 但我无法提供我自己的试用示例,因为我是 MongoDB 新手, 甚至不知道如何接近它。

认为(可能是错误的)如果这是用 SQL Server 编写的,它会如下所示:

给定一个@userID 参数

SELECT distinct s.* 
FROM Subjects s
WHERE @userID = s.subjectCreator
OR 
@userID in (
               SELECT members 
               FROM Groups g 
               WHERE g.GroupID in (
                                       SELECT groups 
                                       FROM Subjects
                                       WHERE s.Groups.GroupID = g.GroupID
                                   )
           )

我的服务器端是用 NodeJS 编写的

还有一个小问题,哪一个是数据库结构的最佳实践? 上面的结构, 还是下面的结构? 区别在于数组,请解释原因

Subjects Collection
 - id : ObjectID(own)
 - subjectCreator : ObjectID(of a user)
 - groups : Array
            [
                 { groupID: ObjectID(of a group) },
                 { groupID: ObjectID(of a group) },,
                 ....more **OBJECTS**
            ]
 - media : Array
            [
                 { 
                     id : ObjectID(of media)
                     mediaUploader: ObjectID(of user)
                     other properties that not important
                 },
                 { 
                     id : ObjectID(of media)
                     mediaUploader: ObjectID(of user)
                     other properties that not important
                 },

            ]

还有一个 Groups 集合

Groups Collection
 - id : ObjectID(own)
 - groupName: string
 - groupAdmin: ObjectID(of user)
 - members: Array
            [
                 { memberID : ObjectID(of a user) },
                 { memberID : ObjectID(of a user) },
                 ....more objects of members id
            ]

【问题讨论】:

    标签: node.js mongodb join aggregation nested-queries


    【解决方案1】:

    对于第一个问题,我们的策略是使用$lookup 来“合并”这些集合,然后对其进行查询。

    db.collection.Subjetcs.aggregate([
            {
               $lookup: {
                   from: "Groups",
                   let: {group_ids: "$groups"},
                   pipeline: [
                        {
                           $match: {
                              $expr:  {
                                  $in: ["$id", "$$group_ids"]
                              }
                           }
                        }
                   ]
                   as: "group" 
               }
            },
            {
               $match: {
                  $or: [
                      {subjectCreator: ObjectId(givenUserID)},
                      {'group.members': ObjectId(givenUserID)}
                  ]
               }
            },
    ])
    

    在设计方面我会坚持使用前者,它使查询看起来“更干净”,并且根据我的经验,将来无论出于何种原因将[{_id: 1}, {_id: 2}] 转换为[1, 2] 时都会为您节省时间和资源。

    请注意,尽管它们是等效的“力量”,即可以用它来完成什么。

    我也不确定开销会有多大,但我想如果你这样做的话,将那个字段索引为数组对 mongo 来说要容易得多。

    【讨论】:

      猜你喜欢
      • 2023-03-28
      • 1970-01-01
      • 2019-06-18
      • 1970-01-01
      • 2020-01-10
      • 2017-08-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多