MongoDB findOne()返回空子文档数组

MongoDB findOne()返回空子文档数组,mongodb,express,mongoose,Mongodb,Express,Mongoose,我用的是猫鼬和MongoDB v。6.4.1. 我使用以下Mongoose模式定义了一个包含嵌入式子文档的文档集合: import mongoose, { Collection } from 'mongoose'; const connectStr = 'mongodb://localhost/appdb'; mongoose.set('useFindAndModify', false); //Open connection to database mongoose.connect(conne

我用的是猫鼬和MongoDB v。6.4.1. 我使用以下Mongoose模式定义了一个包含嵌入式子文档的文档集合:

import mongoose, { Collection } from 'mongoose';
const connectStr = 'mongodb://localhost/appdb';
mongoose.set('useFindAndModify', false);

//Open connection to database
mongoose.connect(connectStr, {useNewUrlParser: true, useUnifiedTopology: true})
  .then(
    () =>  {console.log(`Connected to ${connectStr}.`)},
    err => {console.error(`Error connecting to ${connectStr}: ${err}`)}
  );

//Define schema that maps to a document in the Users collection in the appdb
//database.
const Schema = mongoose.Schema;

const roundSchema = new Schema({
  date: {type: Date, required: true},
  course: {type: String, required: true},
  type: {type: String, required: true, enum: ['practice','tournament']},
  holes: {type: Number, required: true, min: 1, max: 18},
  strokes: {type: Number, required: true, min: 1, max: 300},
  minutes: {type: Number, required: true, min: 1, max: 240},
  seconds: {type: Number, required: true, min: 0, max: 60},
  SGS: {type: Number, 
        default: function(){return (this.strokes * 60) + (this.minutes * 60) + this.seconds}
       },
  notes: {type: String, required: true}
});

const userSchema = new Schema({
  id: {type: String, required: true}, //unique identifier for user
  password: String, //unencrypted password (for now!)
  displayName: {type: String, required: true}, //Name to be displayed within app
  authStrategy: {type: String, required: true}, //strategy used to authenticate, e.g., github, local
  profileImageUrl: {type: String, required: true}, //link to profile image
  rounds: [roundSchema],
  securityQuestion: {type: String},
  securityAnswer: {type: String, required: function() {return this.securityQuestion ? true: false}}
});

//Convert schema to model
const User = mongoose.model("User",userSchema); 
在Express.js GET路径中,我使用以下代码查询特定文档:

try {
    let thisUser = await User.findOne({id: req.params.userId});
    console.log("thisUser: " + JSON.stringify(thisUser));
    if (!thisUser) {
      return res.status(400).send("No user account with specified userId was found in database.");
    } else {
      return res.status(200).json(thisUser.rounds);
    }
  } catch (err) {
    console.log(err);
    return res.status(400).message("Unexpected error occurred when looking up user in database: " + err);
  }
我的console.log语句确认上述路由实际上获得了所需的文档,例如:

thisUser: {"_id":"5e6704234f3864318caedd12","id":"chundhau@gmail.com","password":"GoCougs20","displayName":"chundhau@gmail.com","authStrategy":"local","profileImageUrl":"https://www.gravatar.com/avatar/4b565c54d37b3f5ad4caa1c129e865b8","securityQuestion":"First pet?","securityAnswer":"Daisy","__v":0,"rounds":[]}
当我在MongoDB Compass社区中查看同一文档时,我可以确认它的
rounds
子文档数组有几个元素:

但是,如上面的
控制台.log
输出所示,
轮数
作为空数组返回。我已经确认(a)
rounds
实际上是一个数组(使用
array.isArray()
),并且(b)
rounds
没有元素(
thisUser.rounds.length==0


难道我不能通过thisUser.rounds访问所有子文档吗?我做错了什么

我找到了一个解决办法。我改变了:

let thisUser = await User.findOne({id: req.params.userId});

不可思议的是,
thisuser.rounds
不再是空的。相反,它包含了我在MongoDB Compass社区中查看文档时可以看到的所有数组元素


虽然这个解决方案有效,但我不知道它为什么有效。如果有人能帮我理解这里发生了什么,我将不胜感激

您使用的是什么版本的Mongo?以下内容有用吗?您还可以显示
roundSchema
和注册模型的指令顺序吗?我已经更新了问题,包括版本号(6.4.1)、
roundSchema
和指令顺序。我看不出你提到我的那篇文章有什么关联。谢谢你的帮助!精益选项告诉Mongoose跳过对结果文档进行水合处理。这使得查询速度更快,内存占用更少,但结果文档是普通的旧JavaScript对象(POJO),而不是Mongoose文档@ManjeetThakur谢谢!为什么这允许我访问文档的子文档?当我没有使用
lean()
选项时,子文档在查询中返回为空数组。你能解释一下吗?
let thisUser = await User.findOne({id: req.params.userId}).lean();