MongoDB
 sql >> Teknologi Basis Data >  >> NoSQL >> MongoDB

Pembuatan Versi Objek Java MongoDB

Ini adalah bagaimana saya akhirnya mengimplementasikan versi untuk entitas MongoDB. Terima kasih kepada komunitas StackOverflow yang telah membantu!

  • Log perubahan disimpan untuk setiap entitas dalam kumpulan riwayat terpisah.
  • Untuk menghindari menyimpan banyak data, kumpulan riwayat tidak menyimpan instance lengkap, tetapi hanya versi pertama dan perbedaan antar versi. (Anda bahkan dapat menghilangkan versi pertama dan merekonstruksi versi "mundur" dari versi saat ini di koleksi utama entitas.)
  • Java Object Diff digunakan untuk menghasilkan perbedaan objek.
  • Agar dapat bekerja dengan koleksi dengan benar, seseorang perlu mengimplementasikan equals metode entitas sehingga tes untuk kunci utama database dan bukan sub properti. (Jika tidak, JavaObjectDiff tidak akan mengenali perubahan properti dalam elemen koleksi.)

Berikut adalah entitas yang saya gunakan untuk membuat versi (getter/setter, dll. dihapus):

// 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;
}

Berikut adalah operasi 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()));
}

Beginilah tampilannya di 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
}

EDIT:Ini kode Pengunjung:

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. Indeks di MongoDB

  2. Hapus banyak dokumen dari mongo dalam satu kueri

  3. Memeriksa apakah ada Indeks di mongodb

  4. Bagaimana MongoDb diinstal oleh Meteor?

  5. MySQL ke MongoDB - Lembar Cheat Admin