MongoDB
 sql >> Cơ Sở Dữ Liệu >  >> NoSQL >> MongoDB

Lập phiên bản đối tượng Java MongoDB

Đây là cách tôi kết thúc việc triển khai lập phiên bản cho các thực thể MongoDB. Cảm ơn cộng đồng StackOverflow đã giúp đỡ!

  • Nhật ký thay đổi được lưu giữ cho từng thực thể trong một bộ sưu tập lịch sử riêng biệt.
  • Để tránh lưu nhiều dữ liệu, bộ sưu tập lịch sử không lưu trữ các phiên bản hoàn chỉnh mà chỉ lưu phiên bản đầu tiên và sự khác biệt giữa các phiên bản. (Bạn thậm chí có thể bỏ qua phiên bản đầu tiên và tạo lại các phiên bản "ngược" so với phiên bản hiện tại trong bộ sưu tập chính của thực thể.)
  • Java Object Diff được sử dụng để tạo ra các khác biệt đối tượng.
  • Để có thể làm việc với các bộ sưu tập một cách chính xác, người ta cần triển khai equals phương pháp của các thực thể để nó kiểm tra khóa chính của cơ sở dữ liệu chứ không phải các thuộc tính phụ. (Nếu không, JavaObjectDiff sẽ không nhận ra các thay đổi thuộc tính trong các phần tử của bộ sưu tập.)

Dưới đây là các thực thể tôi sử dụng để lập phiên bản (getters / setters, v.v. đã bị xóa):

// This entity is stored once (1:1) per entity that is to be versioned
// in an own collection
public class MongoDiffHistoryEntry {
    /* history id */
    private String id;

    /* reference to original entity */
    private String objectId;

    /* copy of original entity (first version) */
    private Object originalObject;

    /* differences collection */
    private List<MongoDiffHistoryChange> differences;

    /* delete flag */
    private boolean deleted;
}

// changeset for a single version
public class MongoDiffHistoryChange {
    private Date historyDate;
    private List<MongoDiffHistoryChangeItem> items;
}

// a single property change
public class MongoDiffHistoryChangeItem {
    /* path to changed property (PropertyPath) */
    private String path;

    /* change state (NEW, CHANGED, REMOVED etc.) */
    private Node.State state;

    /* original value (empty for NEW) */
    private Object base;

    /* new value (empty for REMOVED) */
    private Object modified;
}

Đây là hoạt động saveChangeHistory:

private void saveChangeHistory(Object working, Object base) {
    assert working != null && base != null;
    assert working.getClass().equals(base.getClass());

    String baseId = ObjectUtil.getPrimaryKeyValue(base).toString();
    String workingId = ObjectUtil.getPrimaryKeyValue(working).toString();
    assert baseId != null && workingId != null && baseId.equals(workingId);

    MongoDiffHistoryEntry entry = getObjectHistory(base.getClass(), baseId);
    if (entry == null) {
        //throw new RuntimeException("history not found: " + base.getClass().getName() + "#" + baseId);
        logger.warn("history lost - create new base history record: {}#{}", base.getClass().getName(), baseId);
        saveNewHistory(base);
        saveHistory(working, base);
        return;
    }

    final MongoDiffHistoryChange change = new MongoDiffHistoryChange();
    change.setHistoryDate(new Date());
    change.setItems(new ArrayList<MongoDiffHistoryChangeItem>());

    ObjectDiffer differ = ObjectDifferFactory.getInstance();
    Node root = differ.compare(working, base);
    root.visit(new MongoDiffHistoryChangeVisitor(change, working, base));

    if (entry.getDifferences() == null)
        entry.setDifferences(new ArrayList<MongoDiffHistoryChange>());
    entry.getDifferences().add(change);

    mongoTemplate.save(entry, getHistoryCollectionName(working.getClass()));
}

Đây là cách nó trông giống như trong MongoDB:

{
  "_id" : ObjectId("5040a9e73c75ad7e3590e538"),
  "_class" : "MongoDiffHistoryEntry",
  "objectId" : "5034c7a83c75c52dddcbd554",
  "originalObject" : {
      BLABLABLA, including sections collection etc.
  },
  "differences" : [{
      "historyDate" : ISODate("2012-08-31T12:11:19.667Z"),
      "items" : [{
          "path" : "/sections[[email protected]]",
          "state" : "ADDED",
          "modified" : {
            "_class" : "LetterSection",
            "_id" : ObjectId("5034c7a83c75c52dddcbd556"),
            "letterId" : "5034c7a83c75c52dddcbd554",
            "sectionIndex" : 2,
            "stringContent" : "BLABLA",
            "contentMimetype" : "text/plain",
            "sectionConfiguration" : "BLUBB"
          }
        }, {
          "path" : "/sections[[email protected]]",
          "state" : "REMOVED",
          "base" : {
            "_class" : "LetterSection",
            "_id" : ObjectId("5034c7a83c75c52dddcbd556"),
            "letterId" : "5034c7a83c75c52dddcbd554",
            "sectionIndex" : 2,
            "stringContent" : "BLABLABLA",
            "contentMimetype" : "text/plain",
            "sectionConfiguration" : "BLUBB"
          }
        }]
    }, {
      "historyDate" : ISODate("2012-08-31T13:15:32.574Z"),
      "items" : [{
          "path" : "/sections[[email protected]]/stringContent",
          "state" : "CHANGED",
          "base" : "blub5",
          "modified" : "blub6"
        }]
    },
    }],
  "deleted" : false
}

CHỈNH SỬA:Đây là mã Khách truy cập:

public class MongoDiffHistoryChangeVisitor implements Visitor {

private MongoDiffHistoryChange change;
private Object working;
private Object base;

public MongoDiffHistoryChangeVisitor(MongoDiffHistoryChange change, Object working, Object base) {
    this.change = change;
    this.working = working;
    this.base = base;
}

public void accept(Node node, Visit visit) {
    if (node.isRootNode() && !node.hasChanges() ||
        node.hasChanges() && node.getChildren().isEmpty()) {
        MongoDiffHistoryChangeItem diffItem = new MongoDiffHistoryChangeItem();
        diffItem.setPath(node.getPropertyPath().toString());
        diffItem.setState(node.getState());

        if (node.getState() != State.UNTOUCHED) {
            diffItem.setBase(node.canonicalGet(base));
            diffItem.setModified(node.canonicalGet(working));
        }

        if (change.getItems() == null)
            change.setItems(new ArrayList<MongoDiffHistoryChangeItem>());
        change.getItems().add(diffItem);
    }
}

}


  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Cách tổng hợp theo năm-tháng-ngày trên một múi giờ khác

  2. Mongoose luôn trả về một mảng trống NodeJS

  3. Chuyển đổi ObjectID (Mongodb) thành Chuỗi trong JavaScript

  4. Tự động hóa MongoDB với SaltStack

  5. Làm cách nào để lấy nhiều tài liệu bằng mảng id MongoDb?