Mongoose/MongoDB 结果字段在 Javascript 中显示为未定义

IT技术 javascript mongodb mongoose javascript-objects function-prototypes
2021-03-07 00:58:42

是否有什么我遗漏的东西可以允许项目作为带有参数的对象记录,但是当我尝试访问该参数时,它是未定义的?

到目前为止我尝试过的:

  • console.log(item)=>{ title: "foo", content: "bar" }没关系
  • console.log(typeof item) => 对象
  • console.log(item.title) =>“未定义”

我将包括一些上下文,以防万一它与问题相关。

var TextController = function(myCollection) {
  this.myCollection = myCollection
}

TextController.prototype.list = function(req, res, next) {
  this.myCollection.find({}).exec(function(err, doc) {
    var set = new Set([])
    doc.forEach(function(item) {
      console.log(item)         // Here item shows the parameter
      console.log(item.title)   // "undefined"
      set.add(item.title)       
    })
    res.json(set.get());
  })
}

根据我debugger在此行之前删除的建议,以通过节点 repl 调试器检查实际是什么项目。这是我发现的:http : //hastebin.com/qatireweni.sm

从这个我试过console.log(item._doc.title),它工作得很好..所以,这现在看起来更像是一个mongoose问题。

有与此类似的问题,但它们似乎与对象的“this”访问有关,或者他们试图将对象置于函数范围之外。在这种情况下,我认为我没有做任何一个,但如果我错了,请告诉我。谢谢

6个回答

解决方案

您可以调用该toObject方法以访问字段。例如:

var itemObject = item.toObject();
console.log(itemObject.title); // "foo"

为什么

正如您指出的那样,真正的字段存储在_doc文档字段中

但为什么console.log(item)=> { title: "foo", content: "bar" }

mongoose(document.js)的源代码,我们可以发现,该toString方法Document调用的toObject方法。因此console.log将“正确”显示字段。源代码如下所示:

var inspect = require('util').inspect;

...

/**
 * Helper for console.log
 *
 * @api public
 */
Document.prototype.inspect = function(options) {
  var isPOJO = options &&
    utils.getFunctionName(options.constructor) === 'Object';
  var opts;
  if (isPOJO) {
    opts = options;
  } else if (this.schema.options.toObject) {
    opts = clone(this.schema.options.toObject);
  } else {
    opts = {};
  }
  opts.minimize = false;
  opts.retainKeyOrder = true;
  return this.toObject(opts);
};

/**
 * Helper for console.log
 *
 * @api public
 * @method toString
 */

Document.prototype.toString = function() {
  return inspect(this.inspect());
};
我有 Moongose 4.8.4 版,但收到相同的消息错误:“TypeError: user.toObject is not a function”
2021-04-18 00:58:42
@GeorgeRappel 通过引用Historyof Automattic/mongoosetoObject在 3.4.0 版中添加了 。mongoose的最新版本是 4.5.2。我认为你需要更新你的mongoosemodule......
2021-05-03 00:58:42
在 Mongo 3.2 上对我不起作用。说没有toObject办法。
2021-05-07 00:58:42

确保您在架构中定义了标题:

var MyCollectionSchema = new mongoose.Schema({
    _id: String,
    title: String
});
这是我的问题!!!该文档在数据库中是正确的,但由于模式不正确,即使它正确打印了整个对象,它也不会显示变量。
2021-05-11 00:58:42

尝试执行for in循环item,看看您是否可以访问值。

for (var k in item) {
    console.log(item[k]);
}

如果它有效,则意味着您的密钥有一些non-printable字符或类似的东西。

从你在评论中所说的来看,它看起来像是item一个String原始包装器的实例

例如

var s = new String('test');
typeof s; //object
s instanceof String; //true

为了验证这个理论,试试这个:

eval('(' + item + ')').title;

也可能item是一个具有toString显示您所看到内容方法的对象

编辑:要快速识别这些问题,您可以使用console.dir代替console.log,因为它会显示对象属性的交互式列表。您也可以只设置一个断点并添加一个手表。

它将项目显示为字符串,这使得对象的参数无法访问。我已经更新了问题以更好地描述我对正在发生的事情的了解。
2021-04-18 00:58:42
@tippenein,我更新了答案,以便您了解得到的结果。我希望该对象具有toString用于打印自身的自定义函数。这将解释混乱。
2021-04-28 00:58:42
我很欣赏这些解释,但从我最近的发现来看, item._doc.title 返回了我所期望的。这证实了它是一个对象,但是一个对象以某种方式不打印出它实际包含的内容。
2021-04-29 00:58:42
是的!有点。除非我这样做,否则它将对象作为字符串返回。前任"{ title: 'foo'\n content: 'bar'}"
2021-05-08 00:58:42
你的意思是console.log(item[k])显示你说的?
2021-05-14 00:58:42

老问题,但因为我也有这个问题,我会回答它。
这可能是因为您使用的是find()而不是findOne(). 所以最后,你是为一个文档数组而不是一个文档调用一个方法,导致找到一个数组而不是单个文档。使用findOne()将使您可以正常访问该对象。

使用findOne()代替find()

find()方法返回一组值,即使您只有一个可能的结果,您也需要使用 item[0] 来获取它。

findOne方法返回一个对象或不返回一个对象,然后您就可以毫无问题地访问其属性。

原来如此,谢谢!!!没注意到我正在处理一个数组!
2021-04-27 00:58:42