如何使用数据库命令重命名数组中的字段?
如何使用数据库命令重命名数组中的字段?
免责声明:尽管相似,但与MongoDB重命名数组中的数据库字段不同。我想要使用数据库命令而不是shell将字段的键从name
更改为title
。我发现在数组内部使用$rename是不可能的。因此,我转而使用$set和$unset,创建了以下命令:
db.runCommand({ update: 'apps', updates: [ { q: {versions: {$elemMatch: {title: {$exists: false}}}}, u: { $set: {'versions.$.title': '$name'} }, multi: true }, { q: {versions: {$elemMatch: {name: {$exists: true}}}}, u: { $unset: {'versions.$.name': ''} }, multi: true } ] })
这部分代码基本能够实现我的要求,但它将所有的title/name都更改为字符串"$name",而不是字段name
的值。
我还尝试了以下代码:
db.runCommand({ update: 'apps', updates: [ { q: {versions: {$elemMatch: {title: {$exists: false}}}}, u: { $set: { versions: { $map: { input: "versions", as: 'each', in: { "title": "$$each.name" } } } } }, multi: true }, { q: {versions: {$elemMatch: {name: {$exists: true}}}}, u: { $unset: {'versions.$.name': ''} }, multi: true } ] })
但是这只会导致错误[在'versions.$map'中以'$map'为前缀的字段'$'是无效的存储。]
。我该如何在数组内部重命名字段?
以下是我apps集合的精简版本供参考。我只想将名为name
的键更改为title
。
[{ identifier: "x", versions: [ { name: "test_name" version: "x.x.x" }, { name: "test_name" version: "x.x.x" }, ] }, { identifier: "y", versions: [ { name: "test_name2" version: "x.x.x" }, { name: "test_name2" version: "x.x.x" }, ] }, ... ]
如何使用数据库命令重命名数组中的字段?
问题的原因:错误消息提示无效的字段名称,无法存储带有$前缀的字段。
解决方法:
1. 更新聚合管道中的数组字段时,将u对象放在数组括号中。
2. 在$map中同时放入要重命名的字段title和version。
3. 不需要使用$unset,因为$map将使用新字段替换旧数据。
以下是使用数据库命令更新数组字段的示例代码:
db.runCommand({ update: 'apps', updates: [ { q: { "versions.name": { $exists: true } }, u: [{ $set: { versions: { $map: { input: "$versions", in: { "title": "$$this.name", "version": "$$this.version" } } } } }], multi: true } ] })
另一种更动态的方法是使用$mergeObjects和$unset来更新数组字段,代码如下:
db.runCommand({ update: 'apps', updates: [ { q: { "versions.name": { $exists: true } }, u: [ { $set: { versions: { $map: { input: "$versions", in: { $mergeObjects: [ "$$this", { "title": "$$this.name" } ] } } } } }, { $unset: "versions.name" } ], multi: true } ] })
如果没有$map,是否有其他方法遍历数组?
在Azure CosmosDB for MongoDB(3.6版本)中,不支持$map。也无法使用聚合管道进行更新。