database - 将数据类型更新为 mongoDB 中的对象
问题描述
我已将 mongoDB 中集合的一个字段从字符串数组更改为包含 2 个字符串的对象数组。插入新文档没有任何问题,但是当调用 get 方法获取时,查询所有文档时出现此错误:
未能解码“学生”。解码“photoAddresses”时出错:readStartDocument 只能在 CurrentBSONType 为 DOCUMENT 时调用,而 CurrentBSONType 为 STRING 时不能调用。
photoAddresses 是学生中更改的字段。
我想知道有没有办法更新所有记录,使它们都具有相同的数据类型,而不会丢失任何数据。
旧版照片地址:
"photoAddresses" : ["something","something else"]
这应该像这样更新到新版本:
"photoAddresses" : [{photoAddresses:"something"},{photoAddresses:"something else"}]
解决方案
以下聚合查询将字符串数组更新为对象数组,前提是数组具有字符串元素。聚合运算符$map用于将字符串数组元素映射到objects。您可以使用这两个查询中的任何一个。
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+。请注意,更新操作是聚合而不是更新。请参阅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版本:
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 } } ) )
推荐阅读
- symfony4 - 如何修复 Symfony4 中的 RedirectResponse RouteNotFoundException
- python - Tensorflow:将图形中的张量保存到文件(或图像)
- datatable - 数据表搜索选项不起作用
- c# - 如何在规范中生成动态数量的 ThenBy 子句
- amazon-web-services - @reboot 在尝试 ssh 时结束实例
- javascript - 如何在 0 以外的基本角度上执行旋转动画?
- c# - 如何通过用户键入值来增加微调器的数量
- sql - 在进行两个表的内部连接时查找列的最大值
- java - Apache Solr 处理数十万个请求
- javascript - 为什么在全局范围内的 for-of 循环中使用 const 会抛出 TypeError,但在函数内它可以工作?