我有一个mongoDB数据库,它是使用一个脚本生成的,该脚本只使用没有mongoose的node.js mongoDB驱动程序。稍后,在应用程序中,我想使用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
实际匹配:
> 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。
答案 0 :(得分:1)
这个问题的答案在于,从模型Person
自动推断的集合名称mongoose是people
而不是persons
。
问题可以通过写入第一部分中的people
集合或强制mongoose使用集合名称persons
来解决:
const Person = mongoose.model('Person', PersonSchema, 'persons');
mongoose计划删除集合名称中的复数,请参阅Github上的#1350。