At lege med Cursor.observe besvarede mit spørgsmål. Det er måske ikke den mest effektive måde at gøre dette på, men løser mine fremtidige problemer med at afvise DBRefs "links"
Så for serveren skal vi udgive en særlig samling. En, der kan opregne markøren og for hvert dokument søge efter den tilsvarende DBRef. Vær opmærksom på, at denne implementering er hårdkodet og bør udføres som en pakke som UnRefCollection.
Serverside
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();
});
For hvert tilføjet logdokument vil den søge i brugersamlingen og forsøge at tilføje den manglende information til logsamlingen. Den tilføjede funktion kaldes for hvert dokument i logsamlingen i den første kørsel. Jeg oprettede en startupList og en række unikke brugere ids, så for den første kørsel vil den kun forespørge på db én gang. Det er en god idé at sætte en personsøgningsmekanisme til at fremskynde tingene.
Kundeside
På klienten skal du abonnere på logsAndUsers-samlingen, hvis du vil foretage ændringer, skal du gøre det direkte til 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);
});