Mongoose/MongoDB结果字段在Javascript中似乎未定义

Mongoose/MongoDB结果字段在Javascript中似乎未定义,javascript,mongodb,mongoose,javascript-objects,function-prototypes,Javascript,Mongodb,Mongoose,Javascript Objects,Function Prototypes,是否有我遗漏的允许项作为带有参数的对象登录的内容,但当我尝试访问该参数时,它是未定义的 到目前为止,我所尝试的: console.log(item)=>{title:“foo”,content:“bar”},没关系 console.log(项目类型)=>对象 console.log(item.title)=>“未定义” 我将包括一些上下文,以防它与问题相关 var TextController = function(myCollection) { this.myCollection =

是否有我遗漏的允许项作为带有参数的对象登录的内容,但当我尝试访问该参数时,它是未定义的

到目前为止,我所尝试的:

  • console.log(item)
    =>
    {title:“foo”,content:“bar”}
    ,没关系
  • console.log(项目类型)
    =>对象
  • 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 debugger实际是什么项目。这就是我发现的:

从这里我尝试了
console.log(item.\u doc.title)
,效果很好。。所以,这看起来更像是一个猫鼬问题


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

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

var problem = {
    ' title': 'Foo',
    'content': 'Bar'
};
var itemObject = item.toObject();
console.log(itemObject.title); // "foo"

这可能会导致
console.log(item)
显示与预期类似的内容,但在访问
title
属性时,如果没有前面的空格,则会导致
未定义的问题。

是否正在初始化对象

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

var myo1 = new MyObject();

如果未初始化或未设置标题。您将被取消定义。

尝试在
项上执行
for in
循环,查看是否可以访问值

for (var k in item) {
    console.log(item[k]);
}
如果它能工作,则意味着您的密钥有一些
不可打印的
字符或类似的内容

从您在评论中所说的内容来看,
item
似乎是
String
原语包装器的一个实例

例如

要验证此理论,请尝试以下方法:

eval('(' + item + ')').title;
也可能是
item
是一个对象,它有一个
toString
方法来显示您看到的内容


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

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

for (var i = 0; i < doc.length; i++) {
   console.log("iteration " + i);
   console.log('ID:' + docs[i]._id);
   console.log(docs[i].title);
}
for(变量i=0;i
确保已在架构中定义了标题:

var MyCollectionSchema = new mongoose.Schema({
    _id: String,
    title: String
});

这是一个老问题,但既然我也有这个问题,我会回答的。
这可能是因为您使用的是
find()
而不是
findOne()
。因此,最后,您将为文档数组而不是文档调用一个方法,结果是找到一个数组而不是单个文档。使用
findOne()
可以让您正常访问对象。

解决方案 您可以调用
toObject
方法来访问字段。例如:

var problem = {
    ' title': 'Foo',
    'content': 'Bar'
};
var itemObject = item.toObject();
console.log(itemObject.title); // "foo"
为什么? 正如您指出的那样,实际字段存储在文档的
\u doc
字段中

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

从中,我们可以发现
Document
toString
方法调用
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());
};
使用
findOne()
而不是
find()

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


findOne
方法返回一个对象或不返回任何对象,那么您就可以访问它的属性,而不会出现任何问题。

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

doc.toObject({ getters: true })
其他选择包括:

  • getter:
    应用所有getter(路径和虚拟getter)
  • virtuals:
    应用虚拟getter(可以覆盖getter选项)
  • 最小化:
    删除空对象(默认为true)
  • transform:
    返回前应用于结果文档的转换函数
  • 取消填充:
    取消填充任何已填充路径,并将其替换为原始引用(默认为false)
  • versionKey:
    是否包含版本密钥(默认为true)
比如你可以说

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

现在,如果您只想获取信息,而不想获得所有mongoose的好处,那么它将起作用,即,您可以在查询中使用.lean()。它将更快地获取您的信息,您可以直接将其用作对象


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

对象由mongoose集合返回。find({}),但也许您已经了解了一些内容。我初始化TextControllerI可能有问题,我建议使用chrome或firefox开发工具放置断点,以便检查对象的外观。
doc
是mongo db查询的结果,因此我只需迭代这些对象。不过我确实试过了item['title']和item['title']。没有运气!某种程度上。除非我这样做,否则它将以字符串形式返回对象。ex
“{title:'foo'\n content:'bar'}”
您的意思是
console.log(项[k])
显示您所说的内容?它将项显示为字符串,这使得对象的参数无法访问。我更新了这个问题,以便更好地描述我对所发生的事情的了解。@Tippennein,我更新了答案,以便您了解您得到的结果。我想