mongoose#populate returns null in nested object inside array
mongoose#populate returns null in nested object inside array
我有一个 mongoDB 数据库,它是使用脚本生成的,该脚本仅使用 node.js mongoDB driver 而没有 mongoose。稍后,在应用程序中,我想使用 mongoose 加载文档并自动填充引用;然而,这只有 returns null
.
想象一个包含 sub-items 的任务,每个任务都有一个标题和一个指定的人。在这种情况下,指定的人是我想要填充的引用,因此引用存在于任务模式中数组内的 object 中。
下面的代码(需要 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
确实匹配
> 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.
这个问题的答案在于 mongoose 从模型 Person
自动推断出的集合名称是 people
而不是 persons
.
问题可以通过写入第一部分中的 people
集合或强制 mongoose 使用集合名称 persons
:
来解决
const Person = mongoose.model('Person', PersonSchema, 'persons');
无论如何,mongoose 计划删除集合名称中的复数形式,请参阅 Github 上的#1350。
我有一个 mongoDB 数据库,它是使用脚本生成的,该脚本仅使用 node.js mongoDB driver 而没有 mongoose。稍后,在应用程序中,我想使用 mongoose 加载文档并自动填充引用;然而,这只有 returns null
.
想象一个包含 sub-items 的任务,每个任务都有一个标题和一个指定的人。在这种情况下,指定的人是我想要填充的引用,因此引用存在于任务模式中数组内的 object 中。
下面的代码(需要 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
确实匹配
> 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.
这个问题的答案在于 mongoose 从模型 Person
自动推断出的集合名称是 people
而不是 persons
.
问题可以通过写入第一部分中的 people
集合或强制 mongoose 使用集合名称 persons
:
const Person = mongoose.model('Person', PersonSchema, 'persons');
无论如何,mongoose 计划删除集合名称中的复数形式,请参阅 Github 上的#1350。