Database 将数据类型更新为mongoDB中的对象
我已将mongoDB中集合的一个字段从字符串数组更改为包含2个字符串的对象数组。插入新文档时没有任何问题,但当调用get方法以获取时,查询所有文档时,我会收到以下错误: 未能解码“学生”。解码“photoAddresses”时出错 with:readStartDocument只能在CurrentBSONType为时调用 文档,而不是CurrentBSONType为字符串时 photoAddresses是在学生中更改的字段 我想知道是否有办法更新所有记录,使它们都具有相同的数据类型,而不丢失任何数据 照片地址的旧版本:Database 将数据类型更新为mongoDB中的对象,database,mongodb,types,Database,Mongodb,Types,我已将mongoDB中集合的一个字段从字符串数组更改为包含2个字符串的对象数组。插入新文档时没有任何问题,但当调用get方法以获取时,查询所有文档时,我会收到以下错误: 未能解码“学生”。解码“photoAddresses”时出错 with:readStartDocument只能在CurrentBSONType为时调用 文档,而不是CurrentBSONType为字符串时 photoAddresses是在学生中更改的字段 我想知道是否有办法更新所有记录,使它们都具有相同的数据类型,而不丢失任何数
"photoAddresses" : ["something","something else"]
应将其更新为新版本,如下所示:
"photoAddresses" : [{photoAddresses:"something"},{photoAddresses:"something else"}]
以下聚合查询仅当字符串数组具有字符串元素时,才会将字符串数组更新为对象数组。聚合运算符用于将字符串数组元素映射到对象。您可以使用这两个查询中的任意一个
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+版本。注意,更新操作是聚合而不是更新。看
[EDIT ADD]:以下查询适用于版本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 } } ) )
那么旧文档呢,它们将此字段作为字符串?您希望如何将它们映射到对象?你需要更新你的旧文档。就是这样!我需要将它们更新为新的字符串(数组中的每个字符串都是一个对象,其中一个字符串为null),但我不知道如何做到这一点。你说的“数组中的每个字符串都是一个对象”是什么意思?你能发布你当前和旧的photoAddresses对象吗?@SagarAhuja我在问题中提到了它。我发布了一个答案。请让我知道它是否有用。第一个查询似乎不起作用!不过我不太明白,项目部分是做什么的?第一个查询似乎不起作用!请告诉我你认为什么不起作用。我知道这很有效。它将字符串数组
“photo”:[“photo-1”,“photo-2”]
转换为对象数组:{u id:1,“photo”:[{“addr”:“photo-1”},{“addr”:“photo-2”}]}
。不过我不太理解它,项目部分做什么?与$map
一起使用的$project
将字符串数组转换(映射)为数组对象。是否有3.4版的解决方案!我在本地计算机上运行了这个查询,它运行得非常好。但我的服务器有此版本的mongo,我现在无法升级。两个查询都出现此错误:“errmsg”:“未知顶级运算符:$expr”
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 } } ) )