Mongoose 5.0.15 / MongoDB 3.6.4 转换为数组失败的值 [NaN,NaN]

Posted

技术标签:

【中文标题】Mongoose 5.0.15 / MongoDB 3.6.4 转换为数组失败的值 [NaN,NaN]【英文标题】:Mongoose 5.0.15 / MongoDB 3.6.4 Cast to Array Failed for value [NaN, NaN] 【发布时间】:2018-10-21 23:52:40 【问题描述】:

上下文

这不是duplicate of this

正如下面详细解释的那样,我在网上搜索并阅读了大约 20 篇类似的错误或文章,但目前还没有解决这个问题。

我正在两个不同的操作系统 Windows 8.1 和 Linux/Ubuntu (16.4) 中开发基于位置的应用程序 以下引擎在 Ubuntu 机器上运行;但是,无论依赖版本或操作系统如何,我得到的错误都是完全相同的。

Node.js ~4.2.6 NPM ~ 3.5.2 MongoDB ~ 3.6.4 Mongoose ~5.0.15

目前的行为是什么?

尽管我花了几天时间研究类似的错误并测试/尝试不同的东西,但我还是收到了这个错误。 来自邮递员:


    "errors": 
        "coords": 
        "message": "Cast to Array failed for value \"[ NaN, NaN ]\" at path \"coords\"",
        "name": "CastError",
        "stringValue": "\"[ NaN, NaN ]\"",
        "kind": "Array",
        "value": [
            null,
            null
        ],
        "path": "coords",
        "reason": 
            "message": "Cast to [number] failed for value \"[null]\" at path \"coords\"",
           ....
     "_message": "Location validation failed",
     "message": "Location validation failed: coords: Cast to Array failed for value \"[ NaN, NaN ]\" at 
      path \"coords\", name: Path `name` is required., openingTimes.0.days: Path `days` is required., 
      openingTimes.0.closed: Path `closed` is required.",
       "name": "ValidationError"
  

我的假设是,这不仅是由于 Cast Error 造成的问题,而且此特定 POST 方法的 Schema 存在问题。请注意,相同的 Schema 用于 GET 方法,它就像魅力一样工作。

重现步骤。

在开发的这一点上,我正在设计 API 并使用 Mongoose 的 Schema 对数据进行建模。

这是 API 的模型:

const` mongoose = require("mongoose");
const reviewSchema = new mongoose.Schema(
   author: String,
   rating: $type: Number, required: true, min: 0, max: 5,
   timestamp: $type: Date, "default": Date.now,
    reviewText: String
, typeKey: "$type");

const openingTimeSchema = new mongoose.Schema(
  days: $type: String, required: true,
  opening: String,
  closing: String,
  closed: $type: Boolean, required: true
 , typeKey: "$type");

const locationSchema = new mongoose.Schema(
  name: $type: String, required: true,
  rating: $type: Number, "default": 0, min: 0, max: 5,
  address: String,
  facilities: [String],
  coords: $type: [[Number]], index: '2dsphere', required:true,
  openingTimes: [openingTimeSchema],
  reviews: [reviewSchema]
 , typeKey: "$type");

 mongoose.model("Location", locationSchema);

请注意,我正在使用 typeKey,正如在不同帖子中所建议的那样,以及在 Mongoose 文档中针对 geoJSON 对象的建议。即使不使用typeKey,错误仍然存​​在。

控制器

const mongoose = require("mongoose");
const Loc = mongoose.model("Location");

const theEarth = (function()
const earthRadious = 6371;    
const getRadsFromDistance = (distance) => 
    return parseFloat(distance / earthRadious);
 ;

 return 
    getRadsFromDistance: getRadsFromDistance
 ;

 )();

var sendJsonResponse = (res, status, content) =>
  res.status(status);
  res.json(content);
 ;

module.exports.locationsCreate = (req, res) => 
   Loc.create(
    name: req.body.name,
    address: req.body.address,
    facilities: req.body.facilities,
    coords: [parseFloat(req.body.lng), parseFloat(req.body.lat)],
    openingTimes: [
        days: req.body.days1,
        opening: req.body.opening1,
        closing: req.body.closing1,
        closed: req.body.closed1
     ]
    , function (err, location)
            if (err)
                sendJsonResponse(res, 400, err);
            
            else
                sendJsonResponse(res, 201, location);
            
   );


 ;

预期的行为是 POST Postman 中创建的虚拟位置:

POST /api/locations HTTP/1.1

主机:本地主机:3000

名称:Coffee BlaBlaBla

地址:435 High Street Paradise, Midnowhere

设施:热咖啡、早餐、Wifi

液化天然气:2.3567

纬度:41.5676

第 1 天:周一至周五

开幕 1:上午 8:00

关闭 1:下午 5:00

关闭1:假

缓存控制:无缓存

内容类型:application/x-www-form-urlencoded

如果有眼光的人知道发生了什么,那将是惊人的。 谢谢

【问题讨论】:

Mongoose, CastError: Cast to Array failed for value when trying to save a model that contains a model.的可能重复 我认为正文未正确解析,或者您没有为您的数据选择正确的请求内容类型,或者您发送到后端的 json 对象存在问题。请添加您在您的快递应用程序中使用的正文解析器,并从您定义请求正文等的邮递员界面添加屏幕截图。 @DanCrews 这不是您所指问题的重复。如果您阅读了这篇文章,我已经解决了typetypeFormkeyType 的潜在问题。这是Schema声明的问题,我几乎可以肯定。 GET 方法都检索正确的文档,但没有坐标。当我使用 POST 请求的坐标时,我得到了错误。仍在努力 @num8er 不是正文解析器问题。我使用的 POST 方法在上面的代码中,并且是正确的。啊啊啊。我正在研究这个错误的日子。这很可能是 Mongoose 5.x.x 中对象上的数组的问题,但尚无法确认 您是否尝试将其定义为:$type: [Number]?因为我看到您正在将 2 个数字的数组推送到嵌套数组的字段类型(数组中的数组)。或尝试创建类似的记录:coords: [ [parseFloat(req.body.lng), parseFloat(req.body.lat)] ],(见额外的方括号) 【参考方案1】:

这个问题现在已经解决了。正如怀疑的那样,这与之前在此处和 GitHub 中提出的问题无关。问题是通过 Postman 传递的请求不适合 mongoose schema。这是因为各种文档的字段都有验证要求,因此在制定每个请求时只需一个微小的错误即可引发错误。

当我开始一个一个地测试req.body 元素时,我得到了持续的错误,但是服务器开始正确地记录一些字段,尽管是一个一个地隔离的。在我找到正确的组合之前,我测试了所有领域,这让我大开眼界。与直觉相反,req.body 首先返回一个空对象,因为请求在第一个实例中被破坏。

之前的所有尝试,例如将type更改为keyType,使用body-parser而不是express内置中间件来处理JSON和URL请求等,都是很好的尝试,但都是徒劳的。

感谢大家做出贡献并与我一起研究这个问题。

【讨论】:

以上是关于Mongoose 5.0.15 / MongoDB 3.6.4 转换为数组失败的值 [NaN,NaN]的主要内容,如果未能解决你的问题,请参考以下文章

关于NodeJs为啥要用mongoose操作mongodb

关于NodeJs为啥要用mongoose操作mongodb

Node 使用mongodb的mongoose是否很坑

Mongoose / Mongodb 迁移到 MySQL

MongoDB / Mongoose 一对多关系

mongoose \ mongodb 按一些列表排序? [复制]