38

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

到目前为止我已经尝试过:

  • 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)了,它工作得很好。所以,现在这似乎更像是一个猫鼬问题而不是任何事情。

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

4

11 回答 11

52

解决方案

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

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

为什么

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

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

mongoose(document.js) 的源码中,我们可以找到调用方法的toString方法。因此将“正确”显示字段。源代码如下图所示:DocumenttoObjectconsole.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());
};
于 2016-04-03T13:26:40.423 回答
15

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

var MyCollectionSchema = new mongoose.Schema({
    _id: String,
    title: String
});
于 2015-06-18T20:03:43.817 回答
4

尝试执行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,因为它显示对象属性的交互式列表。您还可以设置断点并添加监视。

于 2013-09-10T03:30:07.693 回答
3

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

于 2016-02-05T09:06:21.903 回答
3

使用findOne()而不是find().

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

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

于 2016-06-25T13:49:33.393 回答
3

解决此类问题的更好方法是像这样doc.toObject()使用

doc.toObject({ getters: true })

其他选项包括:

  • getters:应用所有吸气剂(路径和虚拟吸气剂)
  • virtuals:应用虚拟吸气剂(可以覆盖吸气剂选项)
  • minimize:删除空对象(默认为 true)
  • transform:在返回之前应用于结果文档的转换函数
  • depopulate:删除任何填充的路径,用它们的原始引用替换它们(默认为 false)
  • versionKey:是否包含版本密钥(默认为 true)

所以例如你可以说

Model.findOne().exec((err, doc) => {
   if (!err) {
      doc.toObject({ getters: true })
      console.log('doc _id:', doc._id) // or title
   }
})

现在它可以工作了

于 2018-02-21T15:47:44.293 回答
2

中没有空格或有趣的字符' title',是吗?如果您在对象/地图定义中引用了标识符,则可以定义它们。例如:

var problem = {
    ' title': 'Foo',
    'content': 'Bar'
};

这可能会导致console.log(item)显示类似于您所期望的内容,但是当您在没有前面空格的情况下undefined访问该属性时会导致您的问题。title

于 2013-09-10T03:01:14.860 回答
2

我认为使用“查找”方法会返回一个文档数组。我试过这个,我能够打印标题

for (var i = 0; i < doc.length; i++) {
   console.log("iteration " + i);
   console.log('ID:' + docs[i]._id);
   console.log(docs[i].title);
}
于 2014-02-11T04:56:02.617 回答
2

如果您只想获取没有猫鼬所有好处的信息,请保存即,您可以在查询中使用 .lean() 。它将更快地获取您的信息,您可以直接将其用作对象。

https://mongoosejs.com/docs/api.html#query_Query-lean

正如文档中所说,这是最好的只读方案。

于 2018-10-23T15:25:22.983 回答
0

你在初始化你的对象吗?

function MyObject()
{
    this.Title = "";
    this.Content = "";
}

var myo1 = new MyObject();

如果您没有初始化或没有设置标题。你会得到不确定的。

于 2013-09-10T03:02:37.850 回答
0

当您进行周二查询时,请使用.lean()Eg

const order = await Order.findId("84578437").lean()
于 2022-01-20T20:06:10.880 回答