sql >> Database >  >> NoSQL >> MongoDB

Meteor en DBrefs

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);
});


  1. Controleer het huidige aantal verbindingen met MongoDb

  2. object van redis krijgen zonder eval?

  3. Query IDE voor MongoDB?

  4. Een getal opmaken als een percentage in SQL