Spelen met Cursor.observe beantwoordde mijn vraag. Het is misschien niet de meest effectieve manier om dit te doen, maar het lost mijn toekomstige problemen op met het uitstellen van DBRefs-"links"
Dus voor de server moeten we een speciale collectie publiceren. Een die de cursor kan inventariseren en voor elk document kan zoeken naar de bijbehorende DBRef. Houd er rekening mee dat deze implementatie hardgecodeerd is en moet worden gedaan als een pakket zoals UnRefCollection.
Serverzijde
CC.Logs = new Meteor.Collection("logs");
CC.Users = new Meteor.Collection("users");
Meteor.publish('logsAndUsers', function (page, size) {
var self = this;
var startup = true;
var startupList = [], uniqArr = [];
page = page || 1;
size = size || 100;
var skip = (page - 1) * size;
var cursor = CC.Logs.find({}, {limit : size, skip : skip});
var handle = cursor.observe({
added : function(doc, idx){
var clone = _.clone(doc);
var refId = clone.user_id.oid; // showld search DBRefs
if (startup){
startupList.push(clone);
if (!_.contains(uniqArr, refId))
uniqArr.push(refId);
} else {
// Clients added logs
var deref = CC.Users.findOne({_id : refid});
clone.user = deref;
self.set('logsAndUsers', clone._id, clone);
self.flush();
}
},
removed : function(doc, idx){
self.unset('logsAndUsers', doc._id, _.keys(doc));
self.flush();
},
changed : function(new_document, idx, old_document){
var set = {};
_.each(new_document, function (v, k) {
if (!_.isEqual(v, old_document[k]))
set[k] = v;
});
self.set('logsAndUsers', new_document._id, set);
var dead_keys = _.difference(_.keys(old_document), _.keys(new_document));
self.unset('logsAndUsers', new_document._id, dead_keys);
self.flush();
},
moved : function(document, old_index, new_index){
// Not used
}
});
self.onStop(function(){
handle.stop();
});
// Deref on first Run
var derefs = CC.Users.find({_id : {$in : uniqArr} }).fetch();
_.forEach(startupList, function (item){
_.forEach(derefs, function(ditems){
if (item["user_id"].oid === ditems._id){
item.user = ditems;
return false;
}
});
self.set('logsAndUsers', item._id, item);
});
delete derefs; // Not needed anymore
startup = false;
self.complete();
self.flush();
});
Voor elk toegevoegd logboekdocument wordt de gebruikersverzameling doorzocht en wordt geprobeerd de ontbrekende informatie aan de logboekverzameling toe te voegen. De toegevoegde functie wordt aangeroepen voor elk document in de logboekverzameling in de eerste run. Ik heb een startupList en een reeks unieke gebruikers gemaakt ids dus voor de eerste run zal het de db slechts één keer opvragen. Het is een goed idee om een oproepmechanisme in te voeren om dingen te versnellen.
Klantzijde
Abonneer u op de client op de verzameling logsAndUsers. Als u wijzigingen wilt aanbrengen, doe dit dan rechtstreeks in de verzameling Logboeken.
LogsAndUsers = new Meteor.collection('logsAndUser');
Logs = new Meteor.colection('logs'); // Changes here are observed in the LogsAndUsers collection
Meteor.autosubscribe(function () {
var page = Session.get('page') || 1;
Meteor.subscribe('logsAndUsers', page);
});