Att leka med Cursor.observe svarade på min fråga. Det kanske inte är det mest effektiva sättet att göra detta, men löser mina framtida problem med att avfärda DBRefs "länkar"
Så för servern måste vi publicera en speciell samling. En som kan räkna upp markören och för varje dokument söka efter motsvarande DBRef. Kom ihåg att denna implementering är hårdkodad och bör göras som ett paket som UnRefCollection.
Serversidan
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();
});
För varje tillagd loggdokument kommer den att söka i användarens samling och försöka lägga till den saknade informationen i loggsamlingen. Den tillagda funktionen anropas för varje dokument i loggsamlingen i den första körningen. Jag skapade en startupList och en uppsättning unika användare ids så för den första körningen kommer den att fråga db bara en gång. Det är en bra idé att installera en personsökningsmekanism för att påskynda saker.
Kundsidan
På klienten, prenumerera på logsAndUsers-samlingen, om du vill göra ändringar gör det direkt till Logs-samlingen.
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);
});