sql >> Database teknologi >  >> NoSQL >> MongoDB

Meteor og DBRefs

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


  1. Mongo-forespørgsel, der bruger mongoid i rails-app, der forårsager markørtimeoutfejl

  2. Kan ikke autentificere på mongodb med PHP

  3. Sådan læser du flere sæt gemt på Redis ved hjælp af en kommando eller et LUA-script

  4. Java/MongoDB-forespørgsel efter dato