【问题标题】:Is there a way to create a parent and its child from arguments in one query in Mongoose?有没有办法从 Mongoose 的一个查询中的参数创建父级及其子级?
【发布时间】:2017-01-30 16:45:38
【问题描述】:

假设我有一个这样定义的Person(集合persons):

const personSchema = Schema({
  name: String,
  children: [{
    type: Schema.Types.ObjectId,
    ref: 'Person',
  }],
})
const Person = mongoose.model('Person', personSchema)

我不能将children 直接存储在Person 中,因为两个对象可以链接到同一个child,所以这就是我通过关系这样做的原因。

问题是,假设我想在一个查询中创建一个Person 及其children。我有一个 args 对象来获取数据,定义如下:

const args = { name: 'John', children: [{ name: 'Anna' }, {name: 'Craig'}] }

我需要一个查询来在 persons 集合中创建 3 个文档,名称为 JohnAnnaCraig,它还应该在里面记录 AnnaCraigids Johnchildren 字段,像这样:

{_id: 1, name: "John", children: [2, 3]}
{_id: 2, name: "Anna"}
{_id: 3, name: "Craig"}

我试图将这个args 传递给这样的创建函数:

Person.create(args)

它抱怨children 数组不是ObjectIds 的数组。

我猜(还没有测试)如果我用personSchema 替换childrentype,它会创建一个嵌套文档,这是我不想要的。

所以,问题是:Mongoose 有没有一种方法可以在一个查询中执行我想要的操作? (我也知道我可以执行多个查询来保存每个孩子然后保存父母,但有些事情告诉我这不是应该做的,应该有更简单的方法来做到这一点)。

【问题讨论】:

    标签: mongodb mongoose foreign-keys mongoose-schema nosql


    【解决方案1】:

    尝试以下方法插入此类文档:

    使用集合插入查询插入对象数组: 例如:

    PersonModel.collection.insert({ name: 'John', children: [{ name: 'Anna' }, {name: 'Craig'}] }, function() {
        console.log("insert person data");
    });
    

    文档:

    {
        "_id" : ObjectId("57e8da5e6be4d87da7824d29"),
        "name" : "John",
        "children" : [ 
            {
                "name" : "Anna"
            }, 
            {
                "name" : "Craig"
            }
        ]
    }
    

    如果您想为每个子对象设置 _id,那么您必须使用 objectId 构造函数手动生成 objectId:

    var mongoose = require('mongoose');

    PersonModel.collection.insert({
        name: 'John',
        children: [{
            _id: mongoose.Types.ObjectId(),
            name: 'Anna'
        }, {
            _id: mongoose.Types.ObjectId(),
            name: 'Craig'
        }]
    }, function() {
        console.log("insert person data");
    });
    

    输出:

    {
        "_id" : ObjectId("57e8dcd76e620c680d850ebe"),
        "name" : "John",
        "children" : [ 
            {
                "_id" : ObjectId("57e8dcd56e620c680d850eba"),
                "name" : "Anna"
            }, 
            {
                "_id" : ObjectId("57e8dcd56e620c680d850ebb"),
                "name" : "Craig"
            }
        ]
    }
    

    更新:

    var mongoose = require('mongoose');
    
    PersonModel.collection.insert([{
        name: 'Anna'
    }, {
        name: 'Craig'
    }], {
        ordered: true
    }, function(err, data) {
        //console.log(data);
        var parent = {
            name: 'john',
            children: data.insertedIds
        };
        new PersonModel(parent).save()
    
    });
    

    【讨论】:

    • 这将创建 1 个嵌套文档,我需要创建 3 个单独的文档
    • 正如您在问题中提到的,没有必要使用单独的查询来保存所有孩子和父母。您可以使用相同的查询创建所有文档,但要设置子项,您必须点击另一个查询。我会更新我的答案。
    猜你喜欢
    • 2018-08-15
    • 1970-01-01
    • 1970-01-01
    • 2015-05-17
    • 2017-02-18
    • 1970-01-01
    • 2022-06-10
    • 2015-05-31
    • 1970-01-01
    相关资源
    最近更新 更多