MongoDB-design for revisioned data -
there many articles , questions mongodb data-model storing old revisions of documents.
however, found nothing satisfying 1 of requirements; need able retroactively query database unambiguously find documents matched arbitrary criteria given point in time.
to clarify, need able efficiently answer question;
"which documents (and preferably versions) matched criteria {x:y...} @ time t".
pseudocode:
/* match version active 2010 - 2016-05-01 zipcode 12345 */ db.my_objs.find({zipcode: "12345", ~time: isodate("2016-01-01 22:14:31.003")~})
i haven't managed find solution, neither on google nor myself. have tried;
- having simple "from"-timestamp on data, , select "the first item before queried timepoint, matches other criteria", have not managed express in mongo.
- having from/to on each version, , whenever write new version, update "to" on previous version match on new version. however, have not found way atomically or eventual consistency, meaning multiple updates wreak havoc , create ambiguous timelines. (double entries same timepoint)
any ideas?
edit undesirable example query #1
db.my_objs.find({ data : { $elemmatch : { : { $lte : isodate('2015-01-01') } } } }, { "data.$" : 1 }).foreach(function (obj) { if(obj.data[0].state == 'active') { printjson(registrar) } })–
aggregation framework , $unwind
phase transforms array single document can create sophisticated $match
condition
example document
{ "_id" : objectid("577275589ea91b3799341aba"), "title" : "test of design", "firstcreated" : isodate("2016-06-28t13:02:16.156z"), "lastupdated" : isodate("2016-06-28t13:02:16.156z"), "firstauthor" : "profesor79", "lastauthor" : "rawler", "versions" : [{ "versionid" : 1.0, "datecreated" : isodate("2015-10-10t00:00:00.000z"), "datepublished" : isodate("2015-10-12t00:00:00.000z"), "isactive" : false, "documnetpayload" : { "a" : 1.0, "b" : 2.0, "c" : 3.0 } }, { "versionid" : 2.0, "datecreated" : isodate("2015-12-10t00:00:00.000z"), "datepublished" : isodate("2015-12-31t00:00:00.000z"), "isactive" : true, "documnetpayload" : { "a" : 1.0, "b" : 3.0, "c" : 30.0 } }, { "versionid" : 3.0, "datecreated" : isodate("2016-01-31t00:00:00.000z"), "datepublished" : isodate("2016-02-21t00:00:00.000z"), "isactive" : true, "documnetpayload" : { "a" : 11.0, "b" : 3.0, "c" : 31.0 } } ] }
aggregation framework example
db.rawler.aggregate([{ $match : { "_id" : objectid("577275589ea91b3799341aba") } }, { $unwind : "$versions" }, { $match : { $and : [{ "versions.datecreated" : { $gt : isodate("2015-10-10t00:00:00.000z") } }, { "versions.datecreated" : { $lte : isodate("2016-01-30t00:00:00.000z") } } ], "versions.datepublished" : { $gt : new date("2015-10-13t00:00:00.000") }, // "versions.versionid" :{$in:[1,3,4,5]}, } }, { $sort : { "versions.datecreated" : -1 } }, ])
Comments
Post a Comment