sql >> Databasteknik >  >> NoSQL >> MongoDB

Meteor och DBRefs

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


  1. Återuppkoppla ECONNREFUSED i NodeJS i Kubernetes-klustret

  2. Hur frågar du efter är inte null i Mongo?

  3. Hur implementerar man en ström av futures för ett blockerande samtal med futures.rs och Redis PubSub?

  4. Behöver jag uttryckligen stänga anslutningen?