更新对象数组mongodb中的第二级嵌套对象

时间:2017-05-25 07:18:09

标签: mongodb

Below is my JSON and I want to update the title:'second title' to title:'new title' inside videos array in the below JSON.

{
    "_id" : "1234",
    "username" : "test",
    "playlists" : [
        {
            "name" : "abc",         
            "videos" : [
                {
                    "title" : "first title"
                    "desc" : "first description",
                },
                {
                    "title" : "second title"
                    "desc" : "second description",
                },
            ]
        },
        {
            "name" : "def",         
            "videos" : [
                {
                    "title" : "third title"
                    "desc" : "third description",
                },
                {
                    "title" : "fourth title"
                    "desc" : "fourth description",
                },
            ]
        },
    ]
}

我将如何做到这一点?我尝试了下面的查询,但没有运气。它总是只更新视频中的第一个对象

db.xyz.update(
{ username: 'test','playlists.videos.title' : 'second title' }, 
{ $set:{'playlists.0.videos.$.title' : "new title" }}
);

如果我用0和1替换$我可以实现我想要的但我没有位置键/索引,因为它可以在任何地方。 我无法对其进行重组,因为我的数据已经采用这种格式。

2 个答案:

答案 0 :(得分:0)

这个嵌套数组文档无法使用位置运算符完成,因为它是limitation of mongoDB

  

但这可以使用聚合的$unwind$group来完成   管道

方法:

$unwind - 用于展开我们的数组,因为我们有两个数组,所以它被使用了两次。

$project - 使用我们想要做的更新来投放文档

$cond - 将条件与聚合管道中的项目一起使用,将所需结果添加到输出

$group - 一旦我们预测了我们想要的结果,我们需要将其恢复为原始文档格式。

$push - 使用push添加数组格式

我们的文档中有两个嵌套数组,现在我们已经取消了它,因此要获取原始文档,我们需要使用$ group和$ push两次。 首先,我们需要对内部数组进行分组和推送,然后是外部数组。

$out - 最后使用它将输出写入集合。在这里,我们可以给出相同的集合名称,用新的结果覆盖它。

Mongo Shell Query以获得所需的结果

db.mycollection.aggregate([
  {
    $unwind: "$playlists"
  },
  {
    $unwind: "$playlists.videos"
  },
  {
    $project: {
      "_id": 1,
      "username": 1,
      "playlists.name": 1,
      "playlists.videos.desc": 1,
      "playlistsvideostitle": {
        $cond: {
          if: {
            $eq: [
              "$playlists.videos.title",
              "second title"
            ]
          },
          then: "My New title",
          else: "$playlists.videos.title"
        }
      }
    }
  },
  {
    $group: {
      _id: {
        "_id": "$_id",
        "username": "$username",
        "playlistname": "$playlists.name"
      },
      "videos": {
        $push: {
          "title": "$playlistsvideostitle",
          "desc": "$playlists.videos.desc"
        }
      }
    }
  },
  {
    $group: {
      _id: "$_id._id",
      "username": {$first: "$_id.username"},
      "playlists": {
        $push: {
          "name": "$_id.playlistname",
          "videos": "$videos"
        }
      }
    }
  },
 {$out:"mycollection"}
])

答案 1 :(得分:-1)

使用mongo 3.6,您可以使用

db.xyz.update(
{"username": "test"},
{$set: {"playlists.$[i].videos.$[j].title": "new title"},
{arrayFilters: [{"i.name": "abc"}, {"j.title": "second title"}]
});