Mongodb - 将数组中的字段移动到另一个父节点中的新数组

时间:2014-05-23 15:43:58

标签: angularjs mongodb

我在mongodb数据库中有以下数据方案。 由于用户交互,可以将条目从CAT_A移动到CAT_B,并且angularjs模型会相应地更改。

[
   {
      "_id":"537f4407cb8a077d396bd73e",
      "cat":"CAT_A",
      "ntype":"category",
      "entries":[
         {
            "title":"111",
            "content":"Content One",
            "ntype":"entry",
            "_id":"537f4407cb8a077d396bd741"
         },
         {
            "title":"222",
            "content":"Content Two",
            "ntype":"entry",
            "_id":"537f4407cb8a077d396bd740"
         },
         {
            "title":"333",
            "content":"Content Three",
            "ntype":"entry",
            "_id":"537f4407cb8a077d396bd73f"
         }
      ]
   },
   {
      "_id":"537f4407cb8a077d396bd742",
      "cat":"CAT_B",
      "ntype":"category",
      "entries":[
         {
            "title":"444",
            "content":"Content Four",
            "ntype":"entry",
            "_id":"537f4407cb8a077d396bd745"
         },
         {
            "title":"555",
            "content":"Content Five",
            "ntype":"entry",
            "_id":"537f4407cb8a077d396bd744"
         },
         {
            "title":"666",
            "content":"Content Six",
            "ntype":"entry",
            "_id":"537f4407cb8a077d396bd743"
         }
      ]
   }
]

如何将这个新模型保存到mongo数据库中,或者真正处理这个问题的最佳方法是什么? 我一直在做的事情:

  1. 只需从数据库中删除所涉及的所有类别(将有2个以上),然后从新模型中重新创建它们。这似乎效率低下,内容字段也可能包含大量数据,这使得http请求变得昂贵。
  2. 与1相同,但将“内容”保留在架构之外,仅为内容创建新集合,并以某种方式将其链接到条目ID。
  3. 从CAT_A中拉出一个条目并推送到CAT_B,一直在努力使这个工作,如果我想保持索引位置,如模型中的那样?即如果我想将CAT_B中的条目6移到CAT_A中的条目1和2之间?
  4. 欢呼声

    编辑新架构:

    var CatSchema = new Schema({
      name    : String,
      ntype   : String,
      incentries: {
        ntype   : String,
        entry_id : { type: Schema.Types.ObjectId, ref: 'Entry' },
        entry_title : String
        }
      });
    
    
    var EntrySchema = new Schema({
      cat : { type: Schema.ObjectId, ref: 'Cat' },
      title : String,
      content : String,
    });
    

    和代码:

    exports.editCat = function (req, res) {
    Cat.update({_id: req.body.old}, 
        {$pull: {'incentries': {'entry_id': req.body.entry}}}, 
        function (err, data) {
        });
    Cat.update({_id: req.body.new}, 
        {$addToSet: { incentries : {'entry_id': req.body.entry, 'entry_title': req.body.entryTitle, ntype: 'entry' }}},
        function (err, data) {
        });
    };
    

1 个答案:

答案 0 :(得分:0)

使用$ pull和$ push:

>db.elements.findOne()
{
    "_id" : ObjectId("537f6ddcd66d3634fe5963f6"),
    "arr" : [
        {
            "_id" : "537f4407cb8a077d396bd73e",
            "cat" : "CAT_A",
            "ntype" : "category",
            "entries" : [
                {
                    "title" : "111",
                    "content" : "Content One",
                    "ntype" : "entry",
                    "_id" : "537f4407cb8a077d396bd741"
                },
                {
                    "title" : "222",
                    "content" : "Content Two",
                    "ntype" : "entry",
                    "_id" : "537f4407cb8a077d396bd740"
                },
                {
                    "title" : "333",
                    "content" : "Content Three",
                    "ntype" : "entry",
                    "_id" : "537f4407cb8a077d396bd73f"
                }
            ]
        },
        {
            "_id" : "537f4407cb8a077d396bd742",
            "cat" : "CAT_B",
            "ntype" : "category",
            "entries" : [
                {
                    "title" : "444",
                    "content" : "Content Four",
                    "ntype" : "entry",
                    "_id" : "537f4407cb8a077d396bd745"
                },
                {
                    "title" : "555",
                    "content" : "Content Five",
                    "ntype" : "entry",
                    "_id" : "537f4407cb8a077d396bd744"
                },
                {
                    "title" : "666",
                    "content" : "Content Six",
                    "ntype" : "entry",
                    "_id" : "537f4407cb8a077d396bd743"
                }
            ]
        }
    ]
}
> db.elements.update({"_id" : ObjectId("537f6ddcd66d3634fe5963f6")},{$pull:{"arr.0.entries":entry},$push:{"arr.1.entries":entry}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

>db.elements.findOne()
{
    "_id" : ObjectId("537f6ddcd66d3634fe5963f6"),
    "arr" : [
        {
            "_id" : "537f4407cb8a077d396bd73e",
            "cat" : "CAT_A",
            "ntype" : "category",
            "entries" : [
                {
                    "title" : "222",
                    "content" : "Content Two",
                    "ntype" : "entry",
                    "_id" : "537f4407cb8a077d396bd740"
                },
                {
                    "title" : "333",
                    "content" : "Content Three",
                    "ntype" : "entry",
                    "_id" : "537f4407cb8a077d396bd73f"
                }
            ]
        },
        {
            "_id" : "537f4407cb8a077d396bd742",
            "cat" : "CAT_B",
            "ntype" : "category",
            "entries" : [
                {
                    "title" : "444",
                    "content" : "Content Four",
                    "ntype" : "entry",
                    "_id" : "537f4407cb8a077d396bd745"
                },
                {
                    "title" : "555",
                    "content" : "Content Five",
                    "ntype" : "entry",
                    "_id" : "537f4407cb8a077d396bd744"
                },
                {
                    "title" : "666",
                    "content" : "Content Six",
                    "ntype" : "entry",
                    "_id" : "537f4407cb8a077d396bd743"
                },
                {
                    "title" : "111",
                    "content" : "Content One",
                    "ntype" : "entry",
                    "_id" : "537f4407cb8a077d396bd741"
                }
            ]
        }
    ]
}

但你必须知道CAT_A和CAT_B在数组中的位置(位置0和位置1)

您也可以尝试这样的架构:

{
  "_id" : ObjectId("537f6dddd66d3634fe5963f7"),
  "categories" : {
    CAT_A: {
      "_id" : "537f4407cb8a077d396bd73e",
      "cat" : "CAT_A",
      "ntype" : "category",
      "entries" : [...]
    },
    CAT_B:{
      "_id" : "537f4407cb8a077d396bd742",
      "cat" : "CAT_B",
      "ntype" : "category",
      "entries" : [...]
    }
  }
}

所以你更新查询最终会是:

> db.elements.update({"_id" : ObjectId("537f6ddcd66d3634fe5963f6")},{$pull:{"categories.CAT_B.entries":entry},$push:{"categories.CAT_A.entries":entry}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

只要你" cat"字段在单个文档中是唯一的,这个其他方法对我来说似乎更好。