MongooseError:转换为嵌入式值失败

问题描述 投票:0回答:6

我正在创建猫鼬架构,但我得到了

MongooseError

这是我的方案:

let RestaurantSchema = new Schema({
    ratings: {
        type: [{
            id: Number,
            value: Number,
            _id: false
        }],
        default: [
            { id: 1, value: 0 },
            { id: 2, value: 0 },
            { id: 3, value: 0 },
            { id: 4, value: 0 },
            { id: 5, value: 0 }
        ]
    },
    menu: [{
        ratings: {
            type: [{
                id: Number,
                value: Number,
                _id: false
            }],
            default: [
                { id: 1, value: 0 },
                { id: 2, value: 0 },
                { id: 3, value: 0 },
                { id: 4, value: 0 },
                { id: 5, value: 0 }
            ]
        }
    }]
})

这是我收到的错误:

/var/app/node_modules/mongoose/lib/schema/documentarray.js:322
             throw new CastError('embedded', valueInErrorMessage,
             ^
 MongooseError: Cast to embedded failed for value "{ id: 5, value: 0 }" at path "rating"
     at CastError (/var/app/node_modules/mongoose/lib/error/cast.js:26:11)
     at DocumentArray.cast (/var/app/node_modules/mongoose/lib/schema/documentarray.js:322:19)
     at DocumentArray.SchemaType.getDefault (/var/app/node_modules/mongoose/lib/schematype.js:616:23)
     at EmbeddedDocument.Document.$__buildDoc (/var/app/node_modules/mongoose/lib/document.js:265:22)
     at EmbeddedDocument.Document (/var/app/node_modules/mongoose/lib/document.js:61:20)
     at EmbeddedDocument [as constructor] (/var/app/node_modules/mongoose/lib/types/embedded.js:31:12)
     at new EmbeddedDocument (/var/app/node_modules/mongoose/lib/schema/documentarray.js:70:17)
     at DocumentArray.SchemaArray [as constructor] (/var/app/node_modules/mongoose/lib/schema/array.js:67:21)
     at new DocumentArray (/var/app/node_modules/mongoose/lib/schema/documentarray.js:31:13)
     at Function.Schema.interpretAsType (/var/app/node_modules/mongoose/lib/schema.js:643:16)
     at Schema.path (/var/app/node_modules/mongoose/lib/schema.js:563:29)
     at Schema.add (/var/app/node_modules/mongoose/lib/schema.js:445:12)
     at new Schema (/var/app/node_modules/mongoose/lib/schema.js:99:10)
     at Object.<anonymous> (/var/app/models/restaurant.js:12:24)
     at Module._compile (module.js:571:32)
     at Object.Module._extensions..js (module.js:580:10)
     at Module.load (module.js:488:32)
     at tryModuleLoad (module.js:447:12)
     at Function.Module._load (module.js:439:3)
     at Module.require (module.js:498:17)
     at require (internal/module.js:20:19)
     at Object.<anonymous> (/var/app/controllers/restaurant.js:6:18)
     at Module._compile (module.js:571:32)
     at Object.Module._extensions..js (module.js:580:10)
     at Module.load (module.js:488:32)
     at tryModuleLoad (module.js:447:12)
     at Function.Module._load (module.js:439:3)
     at Module.require (module.js:498:17) 

我做错了什么?

node.js mongodb mongoose
6个回答
9
投票

不一定与上述情况相关,但出现此错误的情况(正如我所发生的那样)是当架构需要一个对象,但代码尝试保存到数组时。即,如果:

var MySubSchema = new Schema(
    {
        type: String,
        meta: String
    }
)

var MySchema = new Schema(
    subSchema: MySubSchema,
    otherSubSchema: OtherSubSchema 
)

但是保存数据的路由/控制器如下:

var mySchemaObj = new MySchema(
  {mySubSchema: [new MySubSchema(  //<-- Shouldn't have array "[" here
       {
          type: "foo",
          meta: "bar"
       }
    )]
  } 
)

. . . 
. . . 

mySchemaObj.save() . . . // <-- This will throw the "Cast to Embedded Failed" error, because MySchema expects a single MySubSchema Object, but the code above instantiates MySubSchema in an array. 

5
投票

这可能已经晚了,但是对于其他面临与我相同问题的人来说。
假设我有一个类似这样的模式

const sampleSchema = new Schema({
   productId: Number
   productName: String
})

而且,这是我想存储在其中的数据。

{
   productId:"product_1000",
   productName: "sampleProduct"
}

现在,当我尝试将数据存储在其中时,我将收到 CastError:转换为嵌入值失败
你明白我犯的错误了吗?让我详细说明一下,在架构中,productId是一个Number,我尝试store的数据是String。为了实现这一点,我们必须将 ProductId 的类型从 Number 更改为 String

因此,如果您收到 cast error,请再次检查架构。这是一个简单的错误,但我花了很多时间来找出问题所在。


2
投票

这似乎是v4.9.4中

mongoose
的一个错误。事实上,还有另一个错误生成了这个错误。当您使用
type
作为对象
{id: Number,value: Number,_id: false}
而不是数组时,会出现后者:

TypeError: this.__parentArray._markModified is not a function
    at EmbeddedDocument.markModified (/home/user/Desktop/node_modules/mongoose/lib/types/embedded.js:87:24)
    at SingleNested.Subdocument.markModified (/home/user/Desktop/node_modules/mongoose/lib/types/subdocument.js:62:18)
    at SingleNested.Document.$__set (/home/user/Desktop/node_modules/mongoose/lib/document.js:874:10)

这是此处引用的错误。它似乎已经被修复了几次,但又重新出现了。我在here打开了一个关于此问题的新问题。

解决方法与此处所述相同,替换为

node_modules/mongoose/lib/types/embedded.js

EmbeddedDocument.prototype.markModified = function(path) {
  this.$__.activePaths.modify(path);
  if (!this.__parentArray) {
    return;
  }

EmbeddedDocument.prototype.markModified = function(path) {
  this.$__.activePaths.modify(path);
  if (!this.__parentArray || !this.__parentArray._markModified) {
    return;
  }

此外,将模型重新建模为不同的模式有助于调试问题:

let RatingsItemSchema = new mongoose.Schema({
    id: Number,
    value: Number,
    _id: false
});

let RatingsItem = db.model('RatingsItem', RatingsItemSchema);

let RatingsSchema = new mongoose.Schema({
    ratings: {
        type: [RatingsItemSchema],
        default: [
            { id: 1, value: 0 },
            { id: 2, value: 0 },
            { id: 3, value: 0 },
            { id: 4, value: 0 },
            { id: 5, value: 0 }
        ]
    },
    _id: false
});

let RestaurantSchema = new mongoose.Schema({
    ratings: {
        type: [RatingsItemSchema],
        default: [
            { id: 1, value: 0 },
            { id: 2, value: 0 },
            { id: 3, value: 0 },
            { id: 4, value: 0 },
            { id: 5, value: 0 }
        ]
    },
    menu: {
        type: [RatingsSchema]
    }
});

let Ratings = db.model('Ratings', RatingsSchema);
let Restaurant = db.model('Restaurant', RestaurantSchema);

let rest = new Restaurant();
rest.menu.push(new Ratings());
console.log(JSON.stringify(rest, null, 2));

1
投票

在我的例子中,req.body与预定义的猫鼬模式不匹配,我试图保存一个ObjectId数组, 请求主体是:

{
   cart: ["60d9b457a6c11f2a3818051a"]
}

但是猫鼬模式是

cart: [
   {
      product: {
         type: mongoose.Schema.Types.ObjectId,
         ref: 'products'
      }
   }
]

我像这样改变了猫鼬模式以使其工作:

cart: [
   {
      type: mongoose.Schema.Types.ObjectId,
      ref: 'products'
   }
]

1
投票

如果其他人也有和我一样的问题: 当我在 React 项目中使用 uuidv4() 设置对象

_id
时遇到了这个问题,所以当我的 API 收到包含长 v4() 字符串的
_id
对象时,它使我的猫鼬抛出此异常当它尝试持久化对象时:

(部分例外)

  path: 'middleComponents',
  reason: CastError: Cast to ObjectId failed for value "f41b7983-09b8-4463-bf5b-e59a8f7a19f6" (type string) at path "_id"
      at ObjectId.cast (E:\path-to-project\node_modules\mongoose\lib\schema\objectid.js:248:11)
      at ObjectId.SchemaType.applySetters (E:\path-to-project\node_modules\mongoose\lib\schematype.js:1123:12)
      at EmbeddedDocument.$set (E:\path-to-project\node_modules\mongoose\lib\document.js:1309:20)
      at EmbeddedDocument.$set (E:\path-to-project\node_modules\mongoose\lib\document.js:1058:16)
      at EmbeddedDocument.Document (E:\path-to-project\node_modules\mongoose\lib\document.js:148:12)
      at EmbeddedDocument [as constructor] (E:\path-to-project\node_modules\mongoose\lib\types\embedded.js:47:12)
      at new EmbeddedDocument (E:\path-to-project\node_modules\mongoose\lib\schema\documentarray.js:116:17)
      at DocumentArrayPath.cast (E:\path-to-project\node_modules\mongoose\lib\schema\documentarray.js:462:22)
      at DocumentArrayPath.SchemaType.applySetters (E:\path-to-project\node_modules\mongoose\lib\schematype.js:1123:12)
      at DocumentArrayPath.SchemaType._castForQuery (E:\path-to-project\node_modules\mongoose\lib\schematype.js:1601:15)
      at DocumentArrayPath.SchemaType.castForQueryWrapper (E:\path-to-project\node_modules\mongoose\lib\schematype.js:1563:22)
      at castUpdateVal (E:\path-to-project\node_modules\mongoose\lib\helpers\query\castUpdate.js:546:19)
      at walkUpdatePath (E:\path-to-project\node_modules\mongoose\lib\helpers\query\castUpdate.js:366:24)
      at castUpdate (E:\path-to-project\node_modules\mongoose\lib\helpers\query\castUpdate.js:96:7)
      at model.Query._castUpdate (E:\path-to-project\node_modules\mongoose\lib\query.js:4721:10)
      at castDoc (E:\path-to-project\node_modules\mongoose\lib\query.js:4751:18) {
    stringValue: '"f41b7983-09b8-4463-bf5b-e59a8f7a19f6"',
    messageFormat: undefined,
    kind: 'ObjectId',
    value: 'f41b7983-09b8-4463-bf5b-e59a8f7a19f6',
    path: '_id',
    reason: Error: Argument passed in must be a single String of 12 bytes or a string of 24 hex characters
        at new ObjectID (E:\path-to-project\node_modules\bson\lib\bson\objectid.js:59:11)
        at castObjectId (E:\path-to-project\node_modules\mongoose\lib\cast\objectid.js:25:12)
        at ObjectId.cast (E:\path-to-project\node_modules\mongoose\lib\schema\objectid.js:246:12)
        at ObjectId.SchemaType.applySetters (E:\path-to-project\node_modules\mongoose\lib\schematype.js:1123:12)
        at EmbeddedDocument.$set (E:\path-to-project\node_modules\mongoose\lib\document.js:1309:20)
        at EmbeddedDocument.$set (E:\path-to-project\node_modules\mongoose\lib\document.js:1058:16)
        at EmbeddedDocument.Document (E:\path-to-project\node_modules\mongoose\lib\document.js:148:12)
        at EmbeddedDocument [as constructor] (E:\path-to-project\node_modules\mongoose\lib\types\embedded.js:47:12)
        at new EmbeddedDocument (E:\path-to-project\node_modules\mongoose\lib\schema\documentarray.js:116:17)
        at DocumentArrayPath.cast (E:\path-to-project\node_modules\mongoose\lib\schema\documentarray.js:462:22)
        at DocumentArrayPath.SchemaType.applySetters (E:\path-to-project\node_modules\mongoose\lib\schematype.js:1123:12)
        at DocumentArrayPath.SchemaType._castForQuery (E:\path-to-project\node_modules\mongoose\lib\schematype.js:1601:15)
        at DocumentArrayPath.SchemaType.castForQueryWrapper (E:\path-to-project\node_modules\mongoose\lib\schematype.js:1563:22)
        at castUpdateVal (E:\path-to-project\node_modules\mongoose\lib\helpers\query\castUpdate.js:546:19)
        at walkUpdatePath (E:\path-to-project\node_modules\mongoose\lib\helpers\query\castUpdate.js:366:24)
        at castUpdate (E:\path-to-project\node_modules\mongoose\lib\helpers\query\castUpdate.js:96:7),
    valueType: 'string'
  },
  valueType: 'string'

0
投票

对于无法解决问题的人,请检查您是否使用包含字符串化字段的对象更新数据:

    return await Realty.findByIdAndUpdate(
        id,
        {
            ...realty,
            $push: { images: { $each: images } },
        },
        { new: true },
    );

images
是绝对有效的 JSON,但对于
realty.images
来说,它是字符串化的 JSON,这对 mongoose 不起作用:看起来在替换之前它会检查
realty
字段的有效性。

© www.soinside.com 2019 - 2024. All rights reserved.