Mongoose查询返回Query对象,字段访问undefined问题求助
Mongoose查询返回Query对象而非目标数据的问题
我有一个名为msgContainer的Mongoose模型,查询指定数据时得到的是大量Query对象内容,拿不到目标数据。尝试访问senderEmail.senderEmailID返回undefined,调用senderEmail.toObject()报错,senderEmail.lean()也没用。
相关代码
const mongoose = require('mongoose') require('dotenv').config() const MONGO_DB = process.env.MONGO_DB const msgContainer = require('./msgContainer') const connectDB = async()=>{ await mongoose.connect(MONGO_DB).then((res)=>{ console.log("Mongodb is connected") const senderEmail = msgContainer.find({senderEmailID:"xoti@gmail.com"}) console.log(senderEmail)// 打印这个看不到想要的结果... try{ console.log(senderEmail.senderEmailID)// 访问字段时返回undefined const newMessenger = new msgContainer({ receiverEmailID:"sonu@gmail.com", senderEmailID:"xoti@gmail.com", message:"hello vaiya" }) newMessenger.save() }catch (err){ console.log("err occured") } }).catch((err)=>{ console.log(err,"error occured") })} connectDB();
打印的Query对象内容
Query { _mongooseOptions: {}, _transforms: [], _hooks: Kareem { _pres: Map(0) {}, _posts: Map(0) {} }, _executionStack: null, mongooseCollection: Collection { collection: Collection { s: [Object] }, Promise: [Function: Promise], modelName: 'msgContainer', _closed: false, opts: { autoIndex: true, autoCreate: true, schemaUserProvidedOptions: [Object], capped: false, Promise: [Function: Promise], '$wasForceClosed': undefined }, name: 'msgcontainers', collectionName: 'msgcontainers', conn: NativeConnection { base: [Mongoose], collections: [Object], models: [Object], config: {}, replica: false, options: null, otherDbs: [], relatedDbs: {}, states: [Object: null prototype], _readyState: 1, _closeCalled: undefined, _hasOpened: true, plugins: [], id: 0, _queue: [], _listening: false, _connectionString: 'mongodb+srv://********:******cluster0.fpzt2c9.mongodb.net/?retryWrites=true', _connectionOptions: [Object], client: [MongoClient], '$initialConnection': [Promise], db: [Db], host: 'ac-kpt3plm-shard-00-00.fpzt2c9.mongodb.net', port: 27017, name: 'test' }, queue: [], buffer: false, emitter: EventEmitter { _events: [Object: null prototype] {}, _eventsCount: 0, _maxListeners: undefined, [Symbol(kCapture)]: false } }, model: Model { msgContainer }, schema: Schema { obj: { receiverEmailID: [Object], message: [Array], senderEmailID: [Object] }, paths: { receiverEmailID: [SchemaString], message: [SchemaArray], senderEmailID: [SchemaString], _id: [ObjectId], createdAt: [SchemaDate], updatedAt: [SchemaDate], __v: [SchemaNumber] }, aliases: {}, subpaths: { 'message.$': [SchemaString] }, virtuals: { id: [VirtualType] }, singleNestedPaths: {}, nested: {}, inherits: {}, callQueue: [], _indexes: [], methods: { initializeTimestamps: [Function (anonymous)] }, methodOptions: {}, statics: {}, tree: { receiverEmailID: [Object], message: [Array], senderEmailID: [Object], _id: [Object], createdAt: [Object], updatedAt: [Function: Date], __v: [Function: Number], id: [VirtualType] }, query: {}, childSchemas: [], plugins: [ [Object], [Object], [Object], [Object], [Object] ], '$id': 1, mapPaths: [], s: { hooks: [Kareem] }, _userProvidedOptions: { timestamps: true }, options: { timestamps: true, typeKey: 'type', id: true, _id: true, validateBeforeSave: true, read: null, shardKey: null, discriminatorKey: '__t', autoIndex: null, minimize: true, optimisticConcurrency: false, versionKey: '__v', capped: false, bufferCommands: true, strictQuery: true, strict: true, pluralization: true }, '$timestamps': { createdAt: 'createdAt', updatedAt: 'updatedAt' }, '$globalPluginsApplied': true }, op: 'find', options: {}, _conditions: { senderEmailID: 'xoti@gmail.com' }, _fields: undefined, _update: undefined, _path: undefined, _distinct: undefined, _collection: NodeCollection { collection: Collection { collection: [Collection], Promise: [Function: Promise], modelName: 'msgContainer', _closed: false, opts: [Object], name: 'msgcontainers', collectionName: 'msgcontainers', conn: [NativeConnection], queue: [], buffer: false, emitter: [EventEmitter] }, collectionName: 'msgcontainers' }, _traceFunction: undefined, '$useProjection': true }
期望返回的数据格式
{"_id":{"$oid":"6341746872a157d398c1c387"}, "receiverEmailID":"sonu@gmail.com", "message":["hello bro"], "senderEmailID":"xoti@gmail.com", "createdAt":{"$date":{"$numberLong":"1665234024400"}}, "updatedAt":{"$date":{"$numberLong":"1665234024400"}}, "__v":{"$numberInt":"0"}}
问题原因及解决办法
原因
Mongoose的find()方法返回的是Query对象,不是直接的查询结果。这个对象是用来构建查询的,需要执行后才能拿到数据。直接操作Query对象自然拿不到目标字段,调用toObject()或lean()也无效,因为这些方法需要在查询执行后才能用在结果上。
解决步骤
- 异步执行查询:数据库操作是异步的,必须用
await或者.then()获取结果。 - 调整代码结构:将查询逻辑放入
async函数,配合await使用,或用.then()处理结果。
修改后的代码示例:
const mongoose = require('mongoose') require('dotenv').config() const MONGO_DB = process.env.MONGO_DB const msgContainer = require('./msgContainer') const connectDB = async () => { try { await mongoose.connect(MONGO_DB) console.log("Mongodb is connected") // 使用await执行find查询,拿到实际结果数组 const senderEmails = await msgContainer.find({senderEmailID:"xoti@gmail.com"}) console.log(senderEmails) // 现在能看到目标数据了 // find返回数组,取第一个元素访问字段 if(senderEmails.length > 0) { console.log(senderEmails[0].senderEmailID) } // 保存新数据建议用await,方便捕获错误 const newMessenger = new msgContainer({ receiverEmailID:"sonu@gmail.com", senderEmailID:"xoti@gmail.com", message:"hello vaiya" }) await newMessenger.save() console.log("新消息保存成功") } catch (err) { console.log("错误发生:", err) } } connectDB();
额外说明
- 若只需单个文档,用
findOne()代替find(),它返回单个对象而非数组,更易访问字段:const senderEmail = await msgContainer.findOne({senderEmailID:"xoti@gmail.com"}) lean()需在查询链上调用,比如await msgContainer.find(...).lean(),返回普通JS对象而非Mongoose文档,性能更优。
内容的提问来源于stack exchange,提问作者Bilen
相关产品推荐
相关产品推荐

