mongoose#populate 在数组内的嵌套对象中返回 null
Posted
技术标签:
【中文标题】mongoose#populate 在数组内的嵌套对象中返回 null【英文标题】:mongoose#populate returns null in nested object inside array 【发布时间】:2017-11-17 23:48:18 【问题描述】:我有一个 mongoDB 数据库,它是使用仅使用 node.js mongoDB 驱动程序而不使用 mongoose 的脚本生成的。稍后,在应用程序中,我想使用 mongoose 加载文档并自动填充引用;然而,这只会返回null
。
想象一个包含子项的任务,每个子项都有一个标题和一个指定的人。在这种情况下,分配的人员是我想要填充的引用,因此该引用位于任务模式中数组内的对象中。
下面的代码(需要npm install mongodb mongoose
)重现了这个问题(注意,如果你已经有一个名为test
的本地数据库,它会破坏一个本地数据库):
const mongodb = require('mongodb');
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
(async () =>
// Step 1: Insert data. This is done using the mongodb driver without mongoose.
const db = await mongodb.MongoClient.connect('mongodb://localhost/test');
await db.dropDatabase();
await db.collection('persons').insertOne( name: 'Joe' );
const joe = await db.collection('persons').findOne( name: 'Joe' );
await db.collection('tasks').insertOne( items: [ title: 'Test', person: joe._id ] );
await db.close();
// ================
// Step 2: Create the schemas and models.
const PersonSchema = new Schema(
name: String,
);
const Person = mongoose.model('Person', PersonSchema);
const TaskSchema = new Schema(
items: [
title: String,
person: type: Schema.Types.ObjectId, ref: 'Person' ,
],
);
const Task = mongoose.model('Task', TaskSchema);
// ================
// Step 3: Try to query the task and have it populated.
mongoose.connect('mongodb://localhost/test');
mongoose.Promise = Promise;
const myTask = await Task.findOne().populate('items.person');
// :-( Unfortunately this prints only
// _id: "594283a5957e327d4896d135", items: [ title: 'Test', person: null ]
console.log(JSON.stringify(myTask, null, 4));
mongoose.connection.close();
)();
预期的输出将是
_id: "594283a5957e327d4896d135", items: [ title: 'Test', person: _id: "594283a5957e327d4896d134", name: "Joe" ]
我已经使用 mongo shell 验证了两个 _id
s 实际上匹配:
> db.persons.find()
"_id" : ObjectId("594283a5957e327d4896d134"), "name" : "Joe"
> db.tasks.find()
"_id" : ObjectId("594283a5957e327d4896d135"), "items" : [ "title" : "Test", "person" : ObjectId("594283a5957e327d4896d134") ]
尝试填充person
时我做错了什么?我正在使用 mongoose 4.10.6 和 mongodb 2.2.28。
【问题讨论】:
注意:在populate
调用之后添加.exec()
也不起作用,使用回调代替await
也不起作用。
现在也在猫鼬上以issue #5367 的身份打开。
【参考方案1】:
这个问题的答案在于集合名称mongoose自动从模型Person
推断是people
而不是persons
。
可以通过在第一部分写入people
集合或强制猫鼬使用集合名称persons
来解决问题:
const Person = mongoose.model('Person', PersonSchema, 'persons');
无论如何,mongoose 计划删除集合名称中的复数形式,请参阅 Github 上的 #1350。
【讨论】:
以上是关于mongoose#populate 在数组内的嵌套对象中返回 null的主要内容,如果未能解决你的问题,请参考以下文章