Bermain-main dengan Cursor.observe menjawab pertanyaan saya. Ini mungkin bukan cara yang paling efektif untuk melakukan ini, tetapi memecahkan masalah saya di masa mendatang dalam mendereferensikan "tautan" DBRefs
Jadi untuk server kita perlu menerbitkan koleksi khusus. Salah satu yang dapat menghitung kursor dan untuk setiap dokumen mencari DBRef yang sesuai. Ingatlah bahwa implementasi ini di-hardcode dan harus dilakukan sebagai paket seperti UnRefCollection.
Sisi Server
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();
});
Untuk setiap dokumen log yang ditambahkan, ia akan mencari koleksi pengguna dan mencoba menambahkan informasi yang hilang ke koleksi log. Fungsi yang ditambahkan dipanggil untuk setiap dokumen dalam koleksi log saat pertama kali dijalankan. Saya membuat startupList dan larik pengguna unik id jadi untuk menjalankan pertama itu akan menanyakan db hanya sekali. Ide yang bagus untuk menempatkan mekanisme paging untuk mempercepat sesuatu.
Sisi Klien
Di klien, berlangganan koleksi logsAndUsers, jika Anda ingin membuat perubahan lakukan langsung ke koleksi Log.
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);
});