0

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

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

  • n 个用户
  • 每个用户的 n 个项目
  • 每个项目的 n 个时间条目

我想要实现的是:我想使用 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 $ 位置运算符?
  • 还有其他方法可以在多维数组上推送项目吗?
  • 是否应该在代码级别而不是数据库级别处理此逻辑?
4

1 回答 1

0

您需要使用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
    }
)

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

这将为您提供以下结果:

{
    "_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" : []
                }
            ]
        }
    ]
}
于 2019-09-05T23:04:34.850 回答