MongoDB
 sql >> Baza danych >  >> NoSQL >> MongoDB

Meteor i DBRefs

Zabawa z Cursor.observe odpowiedziała na moje pytanie. Może nie jest to najskuteczniejszy sposób na zrobienie tego, ale rozwiązuje moje przyszłe problemy związane z odraczaniem „łączy” DBRefs

Więc dla serwera musimy opublikować specjalną kolekcję. Taki, który może wyliczyć kursor i dla każdego dokumentu wyszukać odpowiedni DBRef. Pamiętaj, że ta implementacja jest zakodowana na sztywno i powinna być wykonana jako pakiet, taki jak UnRefCollection.

Po stronie serwera

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

Dla każdego dodanego dokumentu z logami przeszuka kolekcję użytkowników i spróbuje dodać do zbioru logów brakujące informacje. Dodana funkcja jest wywoływana dla każdego dokumentu w kolekcji logs w pierwszym uruchomieniu Utworzyłem listę startową i tablicę unikalnych użytkowników ids, więc przy pierwszym uruchomieniu zapyta on db tylko raz. Dobrym pomysłem jest umieszczenie mechanizmu stronicowania, aby przyspieszyć działanie.

Strona klienta

Na kliencie zasubskrybuj kolekcję logsAndUsers, jeśli chcesz wprowadzić zmiany, zrób to bezpośrednio w kolekcji Logs.

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. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Natywne maskowanie MongoDB (trzecia metoda)

  2. Czy w zapytaniu MongoDB można używać ścisłych dat JSON $dates?

  3. Nie udało się połączyć Mongoose z Atlasem

  4. Szyfrowanie bazy danych MongoDB

  5. MongoDB $strLenBytes