为啥猫鼬用“[object Object]”替换子文档?

Posted

技术标签:

【中文标题】为啥猫鼬用“[object Object]”替换子文档?【英文标题】:Why mongoose replaces subdocuments with "[object Object]"?为什么猫鼬用“[object Object]”替换子文档? 【发布时间】:2013-02-26 20:26:53 【问题描述】:

我在使用嵌入式文档时遇到了奇怪的行为,我不知道是我做错了什么还是一个错误。

这是我的模型:

var mg = require('mongoose')
 , S  = mg.Schema;

var subject = new S(
    name: String
  , properties: [
        name: String
      , value: String
    ]
);

module.exports = mg.model('Subject',subject);

当我尝试添加一个属性时,它会以某种方式转换为"[object Object]"

  console.log(req.body); // -->  name: 'height', value: 120 
  console.log(typeof req.body); // --> object
  ob.Subject.findByIdAndUpdate(req.params.id, $push: properties: req.body, function(err, doc) 
    if(err) throw err;
    res.send(doc);
  );

返回的doc 是:

_id: '...', name: 'sss', properties:[ "[object Object]" ]

我使用 mongo CLI 检查数据库中的文档并将正确的值放入其中。

//the document as seen in mongo CLI:

  _id: '...', name: 'sss', 
  properties: [ "[object Object]", name: "aaa", value: "bar" ]

然后我尝试了这个:

ob.Subject.findById(id, function(err, doc) 
  res.send(doc);

然后返回的文档是:

 
  _id: '...', name: 'sss', 
  properties:[ "[object Object]", "[object Object]" ]

我认为,发生的事情是猫鼬以某种方式将子文档转换为该字符串。此外,我不认为这是我的错,或者res.send() 的错,因为:

我没有明确使用 toJsontoObject,我根本不处理 JSON 转换 res.send() 不是问题,因为即使我 util.inspect 的值 - 它是一样的 在通过 mongoose 写入和读取时似乎都发生了无效转换

你有没有遇到过类似的行为?有办法解决吗?

我刚开始使用 mongoose,不知道如何回退到 mongodb 本机来更新和获取文档并检查这种行为是否仍然存在(我怀疑)。

任何有用的提示表示赞赏:)

【问题讨论】:

这里也一样。我发现如果您将子文档定义为架构,例如 var subject = new S( name: String , properties: [SubSchema] );然后它工作正常......对我来说似乎不太正确,因为我将它定义为一个对象,因为只需要一个实例(而不是集合)并且不得不使用一个模式数组,因为模式只能嵌套在 Mongoose 中,如果你将它们嵌入到一个数组中......你找到了更合适的解决方案吗? Is there a way around that? - 是的,它被称为bug report。 【参考方案1】:

我认为您的“属性”属性定义错误。我了解您要做什么,但我怀疑您需要将键/值对定义为它自己的类型,以便您的代码变为:

    var mg = require('mongoose')
     , S  = mg.Schema;

    var keyValue = new S(
        key: String, value: String);

    var subject = new S(
        name: String
      , properties: [keyValue]
    );

    module.exports = mg.model('Subject',subject);

【讨论】:

【参考方案2】:

尽管 Node.js 和 MongoDB 都使用 javascript,但它们并不共享相同的内存空间。他们甚至没有在同一个进程中运行。 因此,他们必须通过 tcp 通信并序列化数据。

我会假设您的 req.body 在格式化 mongoDB 请求时得到 toString()'ed。

编辑

这是正常的,因为您将模型的 properties 属性声明为字符串数组。

就这样声明吧:

properties: Object    

【讨论】:

但是,当我使用 CLI 在文档中放入适当的子文档,然后尝试使用 mongoose 读取文档时,也会发生同样的事情。并且子文档在 CLI 中看起来很正常。只有它的值在find 的某个地方被转换为"[object Object]"【参考方案3】:

你可以试试这个:

ob.Subject.findByIdAndUpdate(req.params.id, $push: properties: name: req.body.name, value: req.body.value, function(err, doc) 
    if(err) throw err;
    res.send(doc);
);

【讨论】:

以上是关于为啥猫鼬用“[object Object]”替换子文档?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 (+)="[object Object][object Object]"? [复制]

“Object [object Object] has no method”错误在线但不在本地主机上!为啥?

当我将 jQuery 选择打印到控制台时,为啥会得到 [object, Object]?

引用分配是原子的,那么为啥需要 Interlocked.Exchange(ref Object, Object)?

为啥 jQuery.cookie 插件返回“[object Object]” [重复]

为啥通过 Vue-router 传递数据返回“[object Object]”?