Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Database 将数据类型更新为mongoDB中的对象_Database_Mongodb_Types - Fatal编程技术网

Database 将数据类型更新为mongoDB中的对象

Database 将数据类型更新为mongoDB中的对象,database,mongodb,types,Database,Mongodb,Types,我已将mongoDB中集合的一个字段从字符串数组更改为包含2个字符串的对象数组。插入新文档时没有任何问题,但当调用get方法以获取时,查询所有文档时,我会收到以下错误: 未能解码“学生”。解码“photoAddresses”时出错 with:readStartDocument只能在CurrentBSONType为时调用 文档,而不是CurrentBSONType为字符串时 photoAddresses是在学生中更改的字段 我想知道是否有办法更新所有记录,使它们都具有相同的数据类型,而不丢失任何数

我已将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 } } ) )