【问题标题】:Pushing objects on a specific multidimensional mongoDb collection在特定的多维 mongoDb 集合上推送对象
【发布时间】:2020-01-08 14:34:52
【问题描述】:

我对 mongoDb 查询语言相当陌生,我正在为以下场景而苦苦挣扎。

我们有一个多维数据集,包括:

  • n 个用户
  • 每个用户有 n 个项目
  • 每个项目有 n 个 time_entries

我想要实现的是:我想使用 collection.update 推送/更新特定项目的 time_entry。

注意每个 pid 对于用户来说应该是唯一的

我使用的集合结构如下:

{
"_id" : ObjectId("5d6e33987f8d7f00c063ceff"),
"date" : "2019-01-01",
"users" : [ 
    {
        "user_id" : 1,
        "projects" : [ 
            {
                "pid" : 1,
                "time_entries" : [ 
                    {
                        "duration" : 1,
                        "start" : "2019-08-29T09:54:56+00:00"
                    }
                ]
            }, 
            {
                "pid" : 2,
                "time_entries" : []
            }
        ]
    },
    {
        "user_id" : 2,
        "projects" : [ 
            {
                "pid" : 3,
                "time_entries" : []
            }
         ]
    }
  ]
}

我目前可以使用以下方法更新给定用户的所有项目:

"users.$.projects.$[].time_entries" 

但我无法针对特定项目,因为该结构包含 2 个嵌套级别,并且在 MongoDb 中还不允许使用多个 $ 位置运算符。

"users.$.projects.$.time_entries"

以下是我的完整查询示例:

db.times.update(
{ 'users' : { $elemMatch : { 'projects' : { $elemMatch : { 'pid' : 153446871 } }  } } },
{ "$push": 
    {
        "users.$.projects.$[].time_entries": 
        {
           "duration" : 5,
           "start" : "2019-08-29T09:54:56+00:00"
        }
    }
}

);

还有其他方法可以达到相同的效果吗?

  • 我是否应该展平数组以便只使用 1 $ 位置运算符?
  • 还有其他方法可以将项目推送到多维数组上吗?
  • 是否应该在代码级别而不是数据库级别处理此逻辑?

【问题讨论】:

    标签: arrays mongodb multidimensional-array positional-operator


    【解决方案1】:

    您需要使用Positional Filtered Operator 来实现:

    db.times.update(
        {}, 
        {
            $push: {
                "users.$[].projects.$[element].time_entries":{
                    "duration" : 5, 
                    "start" : "2019-08-29T09:54:56+00:00"
                }
            }
        },
        { 
            arrayFilters: [{"element.pid":1}], 
            multi: true
        }
    )
    

    该查询会将找到的每个pid = 1 的数据推送到数组time_entries

    这将为您提供以下结果:

    {
        "_id" : ObjectId("5d6e33987f8d7f00c063ceff"),
        "date" : "2019-01-01",
        "users" : [ 
            {
                "user_id" : 1,
                "projects" : [ 
                    {
                        "pid" : 1,
                        "time_entries" : [ 
                            {
                                "duration" : 1,
                                "start" : "2019-08-29T09:54:56+00:00"
                            }, 
                            {
                                "duration" : 5.0,
                                "start" : "2019-08-29T09:54:56+00:00"
                            }
                        ]
                    }, 
                    {
                        "pid" : 2,
                        "time_entries" : []
                    }
                ]
            }, 
            {
                "user_id" : 2,
                "projects" : [ 
                    {
                        "pid" : 3,
                        "time_entries" : []
                    }
                ]
            }
        ]
    }
    

    【讨论】:

      猜你喜欢
      • 2013-08-23
      • 1970-01-01
      • 2015-11-20
      • 2011-12-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多