在mongoDB中将数据类型更新为对象 [英] Updating data type to an Object in mongoDB
问题描述
我将mongoDB中集合的字段之一从字符串数组更改为包含2个字符串的对象数组.插入新文档没有任何问题,但是当调用get方法来获取,查询所有文档时,我得到此错误:
I have changed one of the fields of my collection in mongoDB from an array of strings to an array of object containing 2 strings. New documents get inserted without any problem, but when a get method is called to get , querying all the documents I get this error:
无法解码学生".解码"photoAddresses"错误使用:readStartDocument仅在CurrentBSONType为文档,而不是当CurrentBSONType为STRING时.
Failed to decode 'Students'. Decoding 'photoAddresses' errored with: readStartDocument can only be called when CurrentBSONType is DOCUMENT, not when CurrentBSONType is STRING.
photoAddresses是在学生"中更改的字段.
photoAddresses is the field that was changed in Students.
我想知道有什么方法可以更新所有记录,使它们都具有相同的数据类型,而又不会丢失任何数据.
I was wondering is there any way to update all the records so they all have the same data type, without losing any data.
photoAdresses的旧版本:
The old version of photoAdresses:
"photoAddresses" : ["something","something else"]
应将其更新为新版本,如下所示:
This should be updated to the new version like this:
"photoAddresses" : [{photoAddresses:"something"},{photoAddresses:"something else"}]
推荐答案
仅当数组具有字符串元素时,以下聚合查询才会将字符串数组更新为对象数组.聚合运算符 $ map 用于映射将 string 数组元素添加到 objects .您可以使用两个查询中的任何一个.
The following aggregation queries update the string array to object array, only if the array has string elements. The aggregation operator $map is used to map the string array elements to objects. You can use any of the two queries.
db.test.aggregate( [
{
$match: {
$expr: { $and: [ { $isArray: "$photo" },
{ $gt: [ { $size: "$photo" }, 0 ] }
]
},
"photo.0": { $type: "string" }
}
},
{
$project: {
photo: {
$map: {
input: "$photo",
as: "ph",
in: { addr: "$$ph" }
}
}
}
},
] ).forEach( doc => db.test.updateOne( { _id: doc._id }, { $set: { photo: doc.photo } } ) )
以下查询仅适用于MongoDB 4.2+版本.请注意,更新操作是 aggregation ,而不是 update .参见 updateMany .
db.test.updateMany(
{
$expr: { $and: [ { $isArray: "$photo" },
{ $gt: [ { $size: "$photo" }, 0 ] }
]
},
"photo.0": { $type: "string" }
},
[
{
$set: {
photo: {
$map: {
input: "$photo",
as: "ph",
in: { addr: "$$ph" }
}
}
}
}
]
)
[编辑添加]:以下查询适用于 MongoDB 3.4 版本:
[EDIT ADD]: The following query works with version MongoDB 3.4:
db.test.aggregate( [
{
$addFields: {
matches: {
$cond: {
if: { $and: [
{ $isArray: "$photoAddresses" },
{ $gt: [ { $size: "$photoAddresses" }, 0 ] },
{ $eq: [ { $type: { $arrayElemAt: [ "$photoAddresses", 0 ] } }, "string" ] }
] },
then: true,
else: false
}
}
}
},
{
$match: { matches: true }
},
{
$project: {
photoAddresses: {
$map: {
input: "$photoAddresses",
as: "ph",
in: { photoAddresses: "$$ph" }
}
}
}
},
] ).forEach( doc => db.test.updateOne( { _id: doc._id }, { $set: { photoAddresses: doc.photoAddresses } } ) )
这篇关于在mongoDB中将数据类型更新为对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!