【问题标题】:Why mongoose replaces subdocuments with "[object Object]"?为什么猫鼬用“[object Object]”替换子文档?
【发布时间】:2023-03-04 03:35:01
【问题描述】:

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

这是我的模型:

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

标签: json node.js mongodb mongoose


【解决方案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);
    });
    

    【讨论】:

      猜你喜欢
      • 2016-06-16
      • 2015-11-16
      • 1970-01-01
      • 2015-07-03
      • 2013-10-20
      • 2011-07-13
      • 1970-01-01
      • 2016-10-05
      • 1970-01-01
      相关资源
      最近更新 更多