【问题标题】:mongoose#populate returns null in nested object inside arraymongoose#populate 在数组内的嵌套对象中返回 null
【发布时间】: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 验证了两个 _ids 实际上匹配:

> 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 的身份打开。

标签: node.js mongodb mongoose mongoose-populate


【解决方案1】:

这个问题的答案在于集合名称mongoose自动从模型Person推断是people而不是persons

可以通过在第一部分写入people 集合或强制猫鼬使用集合名称persons 来解决问题:

const Person = mongoose.model('Person', PersonSchema, 'persons');

无论如何,mongoose 计划删除集合名称中的复数形式,请参阅 Github 上的 #1350。

【讨论】:

    猜你喜欢
    • 2013-11-23
    • 2014-08-13
    • 2021-10-20
    • 2014-03-24
    • 2014-08-15
    • 2013-12-17
    • 2015-08-16
    • 1970-01-01
    相关资源
    最近更新 更多