有没有办法从 Mongoose 的一个查询中的参数创建父级及其子级?

Posted

技术标签:

【中文标题】有没有办法从 Mongoose 的一个查询中的参数创建父级及其子级?【英文标题】:Is there a way to create a parent and its child from arguments in one query in 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 有没有一种方法可以在一个查询中执行我想要的操作? (我也知道我可以执行多个查询来保存每个孩子然后保存父母,但有些事情告诉我这不是应该做的,应该有更简单的方法来做到这一点)。

【问题讨论】:

【参考方案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 个单独的文档 正如您在问题中提到的,没有必要使用单独的查询来保存所有孩子和父母。您可以使用相同的查询创建所有文档,但要设置子项,您必须点击另一个查询。我会更新我的答案。

以上是关于有没有办法从 Mongoose 的一个查询中的参数创建父级及其子级?的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法从 Spring Boot 中的参数列表中查询方法名称

Mongoose:如果查询中的参数为空,则忽略该参数

在 Mongoose 中传递 REST URL 参数作为查询条件

Mongoose / Mongodb 迁移到 MySQL

使 mongoose.js 查询同步运行

使 mongoose.js 查询同步运行