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;

  1. having simple "from"-timestamp on data, , select "the first item before queried timepoint, matches other criteria", have not managed express in mongo.
  2. 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

Popular posts from this blog

sql - invalid in the select list because it is not contained in either an aggregate function -

Angularjs unit testing - ng-disabled not working when adding text to textarea -

How to start daemon on android by adb -