Cursor.observe के साथ खेलने से मेरे प्रश्न का उत्तर मिल गया। यह ऐसा करने का सबसे प्रभावी तरीका नहीं हो सकता है, लेकिन डीबीआरएफ "लिंक्स" को संदर्भित करने की मेरी भविष्य की समस्याओं को हल करता है
तो सर्वर के लिए हमें एक विशेष संग्रह प्रकाशित करने की आवश्यकता है। एक जो कर्सर की गणना कर सकता है और प्रत्येक दस्तावेज़ के लिए संबंधित DBRef की खोज कर सकता है। इस कार्यान्वयन को ध्यान में रखते हुए इसे हार्डकोड किया गया है और इसे UnRefCollection जैसे पैकेज के रूप में किया जाना चाहिए।
सर्वर साइड
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();
});
प्रत्येक जोड़े गए लॉग दस्तावेज़ के लिए यह उपयोगकर्ता संग्रह खोजेगा और लॉग संग्रह में लापता जानकारी जोड़ने का प्रयास करेगा। जोड़ा गया फ़ंक्शन लॉग संग्रह में प्रत्येक दस्तावेज़ के लिए पहली बार में कॉल किया जाता है मैंने स्टार्टअप सूची और अद्वितीय उपयोगकर्ताओं की एक सरणी बनाई है आईडी इसलिए पहले रन के लिए यह केवल एक बार डीबी से पूछताछ करेगा। चीजों को गति देने के लिए पेजिंग तंत्र लगाना एक अच्छा विचार है।
ग्राहक पक्ष
क्लाइंट पर, logsAndUsers संग्रह की सदस्यता लें, यदि आप परिवर्तन करना चाहते हैं तो इसे सीधे लॉग संग्रह में करें।
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);
});