javascript - 通过 mongoose 将条目插入 MongoDB 中的多级嵌套数组

标签 javascript node.js mongodb express mongoose

我在后端的 nodejs(express) 中使用 Mongoose 。我的数组结构有三个级别。在第三级,存在一些文件。但我需要根据用户需求在任何级别添加条目。

   [
   {
   "name": "A folder at",
    "route": "level1_a"
  },
  {
    "name":"Another folder at Level1",
    "route": "level1_b",
    "children":
        [
            {
            "name": "A folder at Level2",
            "route": "level1_b/level2_a",
            "children": 
                [
                    {
                    "name": "A folder at Level3",
                    "route": "level1_b/level2_a/level3_a",
                    "children":
                        [
                            {
                            "name": "A file at last level",
                            "route": "level1_b/level2_a/level3_a/file1"
                            },
                            {
                            "name": "Add a new File",
                            "route":"level1_b/level2_a/level3_a/new_file"
                            }
                        ]
                    },
                    {
                    "name": "Add Folder at Level3",
                    "route":"level1_b/level2_a/new_folder"
                    }
                ]
            },
            {
                "name": "Add Folder at level2",
                "route":"level1_b/new_folder"
            }
        ]
  },
  {
      "name": "Add Folder at Level1",
      "route":"new_folder"
  }
]
现在我必须在指定位置添加一个条目。假设在 level2,我需要添加一个文件夹。为了添加,两个参数从 angular 发送到后端。这些将是“名称”和“路线”。所以我的条目将有 {name: 'Products', route: 'level1_a/products'} 并且类似地应该放置在正确的位置,即在 level1_a 的 child 内部。
我的后端有一个架构,如下所示:
const navSchema = mongoose.Schema({
name:{type:String,required:true},
route:{type:String},
children:{
    type: {
    name:{type:String,required:true},
    route:{type:String},
 }}
});
module.exports = mongoose.model('NatItems',navSchema);
API 应该是这样的:
router.post('/navlist',(req,res,next)=>{
  const name= req.body.folder;
  const route= req.body.url;
  console.log(folder,url);//it will be required parameters like name: 'Products', route:'level1_a/products'
  //let pathArray = route.split('/'); //if you want you can split the urls in the array

  //Help me write the code here

  res.status(201).json({
    message:"Post added successfully!"
  })
})
请帮我在数据库中添加条目。我知道 navlist.save() 直接添加一个条目,但我无法以嵌套方式添加条目。
PS:我不能改变数组结构,因为这个数组很容易被angular读取,并且做了一个完整的导航菜单!! 我第一次在 nodejs 和 mongoose 中工作,所以我很难用 mongoose 函数编写代码。

最佳答案

对于您提供的场景 ({name: 'Products', route: 'level1_a/products'}),更新语句非常简单,如下所示:

Model.update(
   { route: "level1_a" }, 
   { $push: { children: {name: 'Products', route: 'level1_a/products'} } })
当传入路由中有两个以上的段时,事情会变得有点复杂,例如
{  "name": "Add a new File", "route":"level1_b/level2_a/level3_a/new_file2" };
在这种情况下,您需要利用 the positional filtered operator 并构建 arrayFilters 并且您的查询变为:
Model.update(
    {  "route": "level1_b"},
    {
        "$push": {
                "children.$[child0].children.$[child1].children": {
                    "name": "Add a new File",
                    "route": "level1_b/level2_a/level3_a/new_file2"
                }
            }
        },
    {
        "arrayFilters": [
            {
                "child0.route": "level1_b/level2_a"
            },
            {
                "child1.route": "level1_b/level2_a/level3_a"
            }
        ]
    })
所以你需要一个函数来循环路由并构建相应的 update 语句和 options :

let obj = {  "name": "Add a new File", "route":"level1_b/level2_a/level3_a/new_file2" };

let segments = obj.route.split('/');;
let query = { route: segments[0] };
let update, options = {};
if(segments.length === 2){
    update = { $push: { children: obj } }
} else {
    let updatePath = "children";
    options.arrayFilters = [];
    for(let i = 0; i < segments.length -2; i++){
        updatePath += `.$[child${i}].children`;
        options.arrayFilters.push({ [`child${i}.route`]: segments.slice(0, i + 2).join('/') });
    }
    
    update = { $push: { [updatePath]: obj } };
    
}

console.log('query', query);
console.log('update', update);
console.log('options', options);

所以你可以运行:
Model.update(query, update, options);

关于javascript - 通过 mongoose 将条目插入 MongoDB 中的多级嵌套数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63858701/

相关文章:

javascript - Angular Js web应用程序数据绑定(bind)无法从Sql数据库中捕获数据

javascript - 在 KonvaJS 上使用带有 globalCompositeOperation 的图像掩码?

node.js - 创建新元素时,我的外键始终为空。 Sequelize , Node ,Postgresql

javascript - 如何在js中循环执行replace

node.js - 是否可以替换或别名 Node.js 中的核心模块?

php - UTCDateTime::toDateTime() 方法返回 1970 日期时间

javascript - 当复选框的容器还包含任何图像时,复选框会触发事件两次

javascript - 从 IE 中的链接调用 JS 函数?

python - PyMongo vs MongoEngine for Django

c# - Mongo C# Driver 2.0 聚合组异常