MongoDB에서 데이터 버전 관리를 어떻게 구현할 것인지 생각을 공유 할 수 있습니까? (나는 카산드라에 대해 비슷한 질문을했다 . 어떤 db가 더 나은지 생각한다면 공유하십시오)
간단한 주소록에 레코드 버전을 지정해야한다고 가정하십시오. 주소록 레코드는 플랫 json 오브젝트로 저장됩니다. 나는 역사를 기대합니다 :
- 자주 사용되지 않습니다
- “타임머신”방식으로 제시하기 위해 한 번에 사용됩니다
- 단일 레코드에 수백 개 이상의 버전이 없습니다. 역사는 만료되지 않습니다.
다음과 같은 접근법을 고려하고 있습니다.
-
레코드 히스토리 또는 레코드 변경 사항을 저장할 새 오브젝트 콜렉션을 작성하십시오. 주소록 항목을 참조하여 버전 당 하나의 개체를 저장합니다. 이러한 기록은 다음과 같습니다.
{ '_id': '새 ID', 'user': user_id, '타임 스탬프': 타임 스탬프, 'address_book_id': '주소록 레코드의 ID' 'old_record': { 'first_name': 'Jon', 'last_name': 'Doe'...} }
이 접근 방식은 문서 당 여러 버전의 버전을 저장하도록 수정할 수 있습니다. 그러나 이것은 이점이없는 느린 접근 방식 인 것 같습니다.
-
주소록 항목에 첨부 된 버전을 직렬화 된 (JSON) 객체로 저장합니다. 그러한 객체를 MongoDB 문서에 첨부하는 방법을 잘 모르겠습니다. 아마도 문자열 배열 일 것입니다. ( CouchDB를 사용한 간단한 문서 버전 화 후 모델링 )
답변
이것으로 뛰어들 때 가장 큰 문제는 “변경 세트를 어떻게 저장 하겠습니까? “입니다 .
- 차이?
- 전체 기록 사본?
내 개인적인 접근 방식은 diff를 저장하는 것입니다. 이 diff의 표시는 실제로 특별한 작업이므로 diff를 다른 “역사”컬렉션에 넣을 것입니다.
다른 컬렉션을 사용하여 메모리 공간을 절약합니다. 일반적으로 간단한 쿼리에 대한 전체 기록을 원하지 않습니다. 따라서 히스토리를 오브젝트에서 제외하면 해당 데이터를 조회 할 때 일반적으로 액세스되는 메모리에서이를 유지할 수 있습니다.
인생을 편하게하기 위해 역사 문서에 타임 스탬프 된 diff의 사전을 포함 시키려고합니다. 이 같은:
{
_id : "id of address book record",
changes : {
1234567 : { "city" : "Omaha", "state" : "Nebraska" },
1234568 : { "city" : "Kansas City", "state" : "Missouri" }
}
}
내 인생을 정말 쉽게하기 위해 데이터에 액세스하는 데 사용하는 DataObjects (EntityWrapper 등) 의이 부분을 만들 것입니다. 일반적으로 이러한 개체에는 몇 가지 형식의 기록이 있으므로이 save()
방법을 쉽게 재정 의하여 동시에 변경할 수 있습니다 .
업데이트 : 2015-10
이제 JSON diff를 처리 하기 위한 사양 이있는 것 같습니다 . 이것은 차이점 / 변경 사항을 저장하는보다 강력한 방법 인 것 같습니다.
답변
다른 답변에서 다루지 않은 일부 측면을 다루는 “Vermongo”라는 버전 관리 체계가 있습니다.
이러한 문제 중 하나는 동시 업데이트이며 다른 문제는 문서를 삭제하는 것입니다.
Vermongo는 전체 문서 사본을 쉐도우 컬렉션으로 저장합니다. 일부 유스 케이스의 경우 너무 많은 오버 헤드가 발생할 수 있지만 많은 것을 단순화한다고 생각합니다.
답변
현재 버전과 모든 이전 버전에 대해 단일 문서를 사용하는 또 다른 솔루션이 있습니다.
{
_id: ObjectId("..."),
data: [
{ vid: 1, content: "foo" },
{ vid: 2, content: "bar" }
]
}
data
모든 버전을 포함 합니다 . data
배열되는 순서 새 버전은 얻을 것이다, $push
배열의 끝에 에드. data.vid
버전 ID이며 증분 숫자입니다.
최신 버전을 받으십시오.
find(
{ "_id":ObjectId("...") },
{ "data":{ $slice:-1 } }
)
다음을 통해 특정 버전을 얻으십시오 vid
.
find(
{ "_id":ObjectId("...") },
{ "data":{ $elemMatch:{ "vid":1 } } }
)
지정된 필드 만 반환 :
find(
{ "_id":ObjectId("...") },
{ "data":{ $elemMatch:{ "vid":1 } }, "data.content":1 }
)
새 버전 삽입 : (및 동시 삽입 / 업데이트 방지)
update(
{
"_id":ObjectId("..."),
$and:[
{ "data.vid":{ $not:{ $gt:2 } } },
{ "data.vid":2 }
]
},
{ $push:{ "data":{ "vid":3, "content":"baz" } } }
)
2
는 IS vid
현재 가장 최신 버전의은과 3
삽입하기 새로운 버전입니다. 최신 버전이 필요하기 때문에 vid
다음 버전을 쉽게 얻을 수 있습니다 vid
.nextVID = oldVID + 1
.
$and
조건은 보장됩니다 2
최신입니다vid
.
이 방법으로 고유 인덱스가 필요하지 않지만 애플리케이션 로직은 vid
삽입시 증가를 처리해야 합니다.
특정 버전을 제거하십시오.
update(
{ "_id":ObjectId("...") },
{ $pull:{ "data":{ "vid":2 } } }
)
그게 다야!
(문서 당 16MB 제한을 기억하십시오)
답변
즉시 사용 가능한 솔루션을 찾고 있다면-
Mongoid는 간단한 버전 관리 기능을 내장하고 있습니다.
http://mongoid.org/en/mongoid/docs/extras.html#versioning
mongoid-history는 감사, 실행 취소 및 다시 실행을 통해 훨씬 더 복잡한 솔루션을 제공하는 Ruby 플러그인입니다.
답변
게시 된 초안 및 이전 버전의 데이터를 수용하는이 솔루션을 통해 작업했습니다.
{
published: {},
draft: {},
history: {
"1" : {
metadata: <value>,
document: {}
},
...
}
}
모델을 더 자세히 설명합니다. http://software.danielwatrous.com/representing-revision-data-in-mongodb/
Java 에서 이와 같은 것을 구현할 수있는 사람들을 위한 예제는 다음과 같습니다.
http://software.danielwatrous.com/using-java-to-work-with-versioned-data/
원하는 경우 포크 할 수있는 모든 코드 포함
답변
답변
또 다른 옵션은 mongoose-history 플러그인 을 사용하는 것 입니다.
let mongoose = require('mongoose');
let mongooseHistory = require('mongoose-history');
let Schema = mongoose.Schema;
let MySchema = Post = new Schema({
title: String,
status: Boolean
});
MySchema.plugin(mongooseHistory);
// The plugin will automatically create a new collection with the schema name + "_history".
// In this case, collection with name "my_schema_history" will be created.