【问题标题】:MongoDB $set item in array which does not exists with object as element results in object instead of arrayMongoDB $set 数组中的项不存在,对象作为元素导致对象而不是数组
【发布时间】:2021-07-10 03:55:44
【问题描述】:

这里解释了更新数组中的元素:

https://docs.mongodb.com/manual/reference/operator/update/set/#set-elements-in-arrays

但在文档中似乎缺少文档中尚不存在数组的情况。示例:

如果有这个文件:

{
  _id: 'some-id',
  otherprops: 'value'
}

我希望它变成这样:

{
  // ...
  settings: {
    friends: [
      {
        name: 'John Doe',
        age: 28
      }
    ]
  }
  // ...
}

在这种情况下,我不知道是否已经有一个 settings.friends 数组。所以我的查询看起来像这样:

{
  $set: {
    'settings.friends.0.name': 'John Doe',
    'settings.friends.0.age': 28
  }
}

但是文档的结果是这样的:

{
  // ...
  settings: {
    friends: {
      0: {
        name: 'John Doe',
        age: 28
      }
    }
  }
  // ...
}

有没有办法强制 mongodb 在我的示例中创建一个数组而不是一个对象但只使用点符号。

【问题讨论】:

  • 看起来没有办法告诉 MongoDB 结果数据类型必须是什么。默认情况下,MongoDB 将点符号路径转换为对象。您不能将路径转换为特定类型,并且没有明确的语法告诉 MongoDB 提供的路径必须导致数组:(

标签: mongodb mongodb-query


【解决方案1】:

试试这个。

{
    $addToSet: {
        "settings.friends": [
            {
                name: 'John Doe',
                age: 28
            }
        ]
    }
}

【讨论】:

  • 在你的情况下,我不会用点符号来做 - 但我想。原因是:如果我不使用点表示法,我必须检查现有文档是否存在数组。假设您只想对一个属性的文档执行更新。如果我会这样做,那么您已显示其他属性将丢失(如果我不将其与现有文档合并,我不想这样做)
  • 以上更新的代码将满足您的要求
  • 我刚刚看到你的例子也不是我要锁定的。在您的示例中,它总是会向数组添加一个新项目 - 但是如果数组位置 0 上的对象已经存在并且我只想更新属性名称和年龄而不是添加它们怎么办?所以问题还是一样的:How to solve to force mongodb using arrays while doing dot notation?
  • 你可以使用 $set 代替 $addToset
  • ...那么我遇到了我在问题中描述的问题。当我执行 $set 'settings.firends.0.name' 时,mongodb 将保存一个对象而不是数组。
【解决方案2】:

这适用于 mongodb 版本 v4.0.9。我已经在我的机器上测试了你的用例。

db.collection.update(
  {
    "_id": 'your_key'
  },
  {
    "$set": {
      "settings.friends.0.name": "ABCD"
    }
  },
  {
    "upsert": "true"
  }
)

在更新之前我的收藏条目是

{
    "_id" : 2,
    "col1" : "val01",
    "settings" : {
        "friends" : [
            {
                "name" : "Ramraj",
                "age" : 28
            }
        ]
    }
}

更新后我的收藏条目是

{
    "_id" : 2,
    "col1" : "val01",
    "settings" : {
        "friends" : [
            {
                "name" : "ABCD",
                "age" : 28
            }
        ]
    }
}

【讨论】:

  • 这不完全是我的情况。我的情况是“settings.friends”不存在。在你的情况下它存在。
猜你喜欢
  • 2014-08-21
  • 2021-08-13
  • 2021-12-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多