Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MongoDB中实现数据版本控制的方法_Mongodb_Database Versioning - Fatal编程技术网

MongoDB中实现数据版本控制的方法

MongoDB中实现数据版本控制的方法,mongodb,database-versioning,Mongodb,Database Versioning,您能分享一下您的想法吗?您将如何在MongoDB中实现数据版本控制。(我已经问过了。如果您有任何想法,请与我们分享) 假设我需要在一个简单的地址簿中对记录进行版本设置。(通讯簿记录存储为平面json对象)。我希望历史: 将不经常使用 将一次全部使用,以“时间机器”的方式呈现 一条记录的版本不会超过几百个。 历史不会终结 我正在考虑以下方法: 创建新的对象集合以存储记录或记录更改的历史记录。它将为每个版本存储一个对象,并引用地址簿条目。这些记录如下: { '_id': 'new id',

您能分享一下您的想法吗?您将如何在MongoDB中实现数据版本控制。(我已经问过了。如果您有任何想法,请与我们分享)

假设我需要在一个简单的地址簿中对记录进行版本设置。(通讯簿记录存储为平面json对象)。我希望历史:

  • 将不经常使用
  • 将一次全部使用,以“时间机器”的方式呈现
  • 一条记录的版本不会超过几百个。 历史不会终结
我正在考虑以下方法:

  • 创建新的对象集合以存储记录或记录更改的历史记录。它将为每个版本存储一个对象,并引用地址簿条目。这些记录如下:

    { '_id': 'new id', 'user': user_id, 'timestamp': timestamp, 'address_book_id': 'id of the address book record' 'old_record': {'first_name': 'Jon', 'last_name':'Doe' ...} } { “_id”:“新id”, “用户”:用户id, “时间戳”:时间戳, “地址簿id”:“地址簿记录的id” ‘旧唱片’:{‘姓’:‘乔恩’,‘姓’:‘多伊’…} } 可以修改此方法以存储每个文档的版本数组。但这似乎是一种没有任何优势的较慢的方法

  • 将版本存储为附加到通讯簿条目的序列化(JSON)对象。我不知道如何将这些对象附加到MongoDB文档。也许是字符串数组。 ()


当深入到这一点时,第一个大问题是“您希望如何存储变更集”

  • 差别
  • 整张唱片
  • 我个人的做法是存储差异。因为这些差异的显示实际上是一个特殊的动作,所以我会将这些差异放在不同的“历史”集合中

    我会使用不同的集合来节省内存空间。对于一个简单的查询,通常不需要完整的历史记录。因此,通过将历史记录保留在对象之外,您还可以在查询数据时将其保留在通常访问的内存之外

    为了让我的生活更轻松,我会制作一份历史文档,其中包含一本带有时间戳的差异字典。大概是这样的:

    {
        _id : "id of address book record",
        changes : { 
                    1234567 : { "city" : "Omaha", "state" : "Nebraska" },
                    1234568 : { "city" : "Kansas City", "state" : "Missouri" }
                   }
    }
    
    为了让我的生活变得更加轻松,我将把这部分数据对象(EntityWrapper,无论什么)作为访问数据的工具。通常,这些对象具有某种形式的历史记录,因此您可以轻松地重写
    save()
    方法以同时进行此更改

    更新:2015-10


    看来现在有了。这似乎是一种存储差异/更改的更健壮的方法。

    如果您正在寻找一种现成的解决方案-

    Mongoid内置了简单的版本控制

    mongoid history是一个Ruby插件,它提供了一个更复杂的解决方案,包括审计、撤销和重做


    有一个名为“Vermongo”的版本控制方案,它解决了其他答复中未涉及的一些方面

    其中一个问题是并发更新,另一个问题是删除文档

    Vermongo将完整的文档副本存储在卷影集合中。对于某些用例,这可能会导致太多的开销,但我认为这也简化了许多事情


    我使用了这个解决方案,该解决方案包含数据的已发布、草稿和历史版本:

    {
      published: {},
      draft: {},
      history: {
        "1" : {
          metadata: <value>,
          document: {}
        },
        ...
      }
    }
    
    {
    已出版:{},
    草案:{},
    历史:{
    "1" : {
    元数据:,
    文件:{}
    },
    ...
    }
    }
    
    我在此进一步解释该模型:

    对于那些可能在Java中实现类似功能的用户,下面是一个示例:

    包括所有可以分叉的代码,如果您愿意的话


    以下是另一个解决方案,它对当前版本和所有旧版本使用单个文档:

    {
        _id: ObjectId("..."),
        data: [
            { vid: 1, content: "foo" },
            { vid: 2, content: "bar" }
        ]
    }
    
    数据
    包含所有版本。
    数据
    数组是有序的,新版本只能将
    $push
    插入到数组的末尾
    data.vid
    是版本id,是一个递增的数字

    获取最新版本:

    find(
        { "_id":ObjectId("...") },
        { "data":{ $slice:-1 } }
    )
    
    find(
        { "_id":ObjectId("...") },
        { "data":{ $elemMatch:{ "vid":1 } } }
    )
    
    find(
        { "_id":ObjectId("...") },
        { "data":{ $elemMatch:{ "vid":1 } }, "data.content":1 }
    )
    
    update(
        { "_id":ObjectId("...") },
        { $pull:{ "data":{ "vid":2 } } }
    )
    
    通过
    视频获取特定版本:

    find(
        { "_id":ObjectId("...") },
        { "data":{ $slice:-1 } }
    )
    
    find(
        { "_id":ObjectId("...") },
        { "data":{ $elemMatch:{ "vid":1 } } }
    )
    
    find(
        { "_id":ObjectId("...") },
        { "data":{ $elemMatch:{ "vid":1 } }, "data.content":1 }
    )
    
    update(
        { "_id":ObjectId("...") },
        { $pull:{ "data":{ "vid":2 } } }
    )
    
    仅返回指定字段:

    find(
        { "_id":ObjectId("...") },
        { "data":{ $slice:-1 } }
    )
    
    find(
        { "_id":ObjectId("...") },
        { "data":{ $elemMatch:{ "vid":1 } } }
    )
    
    find(
        { "_id":ObjectId("...") },
        { "data":{ $elemMatch:{ "vid":1 } }, "data.content":1 }
    )
    
    update(
        { "_id":ObjectId("...") },
        { $pull:{ "data":{ "vid":2 } } }
    )
    
    插入新版本:(并防止并发插入/更新)

    2
    是当前最新版本的
    vid
    3
    是插入的新版本。因为您需要最新版本的
    vid
    ,所以很容易获得下一版本的
    vid
    nextVID=oldVID+1

    $和
    条件将确保
    2
    是最新的
    vid

    这样就不需要唯一的索引,但应用程序逻辑必须注意在插入时增加
    vid

    删除特定版本:

    find(
        { "_id":ObjectId("...") },
        { "data":{ $slice:-1 } }
    )
    
    find(
        { "_id":ObjectId("...") },
        { "data":{ $elemMatch:{ "vid":1 } } }
    )
    
    find(
        { "_id":ObjectId("...") },
        { "data":{ $elemMatch:{ "vid":1 } }, "data.content":1 }
    )
    
    update(
        { "_id":ObjectId("...") },
        { $pull:{ "data":{ "vid":2 } } }
    )
    
    就这样


    (记住每个文档16MB的限制)

    如果您使用的是mongoose,我发现以下插件是该格式的有用实现

    另一个选择是使用插件


    我在meteor/MongoDB项目中使用了下面的包,它工作得很好,主要优点是它在同一文档的数组中存储历史记录/修订,因此不需要额外的出版物或中间件来访问更改历史记录。它可以支持有限数量的早期版本(例如,最近十个版本),还支持变更串联(因此在特定时间段内发生的所有变更都将包含在一个修订中)


    另一个合理的选择是使用Meteor Vermongo()

    难道您不担心这样的历史文档(更改对象)会随着时间的推移而增长,并且更新会变得效率低下吗?或者MongoDB处理文档是否容易增长?请查看编辑。添加到
    changes
    非常简单:
    db.hist.update({{u id:id},{$set{changes.12345:changes},true)
    这将执行只更改所需数据的upsert。Mongo为ha创建具有“缓冲空间”的文档