2016-10-10 16 views
7

Używam official node.js mongodb client do wykonywania zapytań Mongo kierowanych do klastra za pomocą ciągu połączenia podobnego do: mongodb://euwest1-01,euwest1-02,uswest2-01/dbname?replicaSet=mycluster&readPreference=nearest. Jak widzisz, dołączam do mojego klastra kilka różnych lokalizacji geograficznych, a "najbliższy" powinien gwarantować odpowiednią replikę do pobrania.Pobierz instancję repliki użytą do zapytania mongo za pomocą node.js

Mimo to chciałbym się dowiedzieć, który z nich był użyty do wykonania zapytania, dzięki czemu mogę dołączyć do każdej z moich operacji log 'replikę mongo, która została użyta do wykonania zapytania.

Hacking wokół obiektu Cursor mogę dostać to, co chcę w hacky sposób:

const find = (query, callback) => { 

    let cursor = coll.find(query); 
    cursor.toArray((err, items) => { 
     console.log(cursor.server.ismaster.me); 
     callback(err, items); 
    }); 
}; 

Ale czuję się jak to można przerwać w dowolnym momencie, jak nie udokumentowano + wydaje się ograniczony do interakcji kursor (więc nie wiedziałbym, jak osiągnąć to samo dla metody findOne).

Czy ktoś wie o czystej drodze do zrobienia tego?

+1

Robi to od strony aplikacji wydaje się niewłaściwy sposób do mnie. Proponuję okresowo monitorować podłączonych klientów do każdego członka zestawu replik i alert w przypadku znalezienia klienta, który _ nie powinien należeć do listy klientów. Jednak sposób, w jaki działa "najbliższy", sprawia, że ​​jest absolutnie możliwe, że klient z drugiego końca świata łączy się, ponieważ najbliższy oznacza w zasadzie "ten o najniższym opóźnieniu". Nie pamiętam jednak okresu, w którym ustalono opóźnienie. –

Odpowiedz

2

Użytkownik może być zainteresowany korzystaniem z interfejsu APM.

http://mongodb.github.io/node-mongodb-native/2.2/reference/management/apm/

ta umożliwia dostęp kontekst każdej operacji prowadzony przez kierowcę i ma naprawdę dla dostawców APM ale jeśli chcesz śledzić lub zalogować się w jaki sposób ops realizują to może być przydatne dla Ciebie .

var listener = require('mongodb').instrument({ 
 
    operationIdGenerator: { 
 
    operationId: 1, 
 

 
    next: function() { 
 
     return this.operationId++; 
 
    } 
 
    }, 
 

 
    timestampGenerator: { 
 
    current: function() { 
 
     return new Date().getTime(); 
 
    }, 
 

 
    duration: function(start, end) { 
 
     return end - start; 
 
    } 
 
    } 
 
}, function(err, instrumentations) { 
 
    // Instrument the driver 
 
}); 
 

 
listener.on('started', function(event) { 
 
    // command start event (see https://github.com/mongodb/specifications/blob/master/source/command-monitoring/command-monitoring.rst) 
 
}); 
 

 
listener.on('succeeded', function(event) { 
 
    // command success event (see https://github.com/mongodb/specifications/blob/master/source/command-monitoring/command-monitoring.rst) 
 
}); 
 

 
listener.on('failed', function(event) { 
 
    // command failure event (see https://github.com/mongodb/specifications/blob/master/source/command-monitoring/command-monitoring.rst) 
 
});

-1

Przypuszczam, że nie jest to najlepsze rozwiązanie, ale można użyć funkcji .eval(), aby utworzyć funkcję, która powrotu server_info & rezultacie tak:

db.getCollection('mycollection').eval(function construct(){ 
    var res = db.getCollection('mycollection').find(query); 
    var explain = res.explain()['server']; 
    return {'server':explain,'result':res.toArray()}; 
})() 

które zwracają coś takiego:

{ 
    "server" : "myservernode.mydomain:27017", 
    "result" : [ 
     // your query results 
    ] 
} 
+0

Dziękuję za odpowiedź. Sprawdziłem funkcjonalność wyjaśnienia, niestety 1) Jest ona dostępna tylko dla kursora - więc problem z findOne będzie się utrzymywał - 2) Kiedy uruchomię go dla kursora w węźle, serwer, który dostaję stamtąd wydaje się inny niż to, co mam, kiedy sprawdzam. cursor.server.ismaster.me', więc teraz jestem zdezorientowany :( – matteofigus

+0

1) Więc findOne problem jest normalny, ponieważ metoda findOne() zwraca dokument, a nie kursor. Możesz użyć zamiast metody find() z filtrem, aby uzyskać tylko 1 element –

+0

2) Użyj eval() więcej niż twoja metoda. Komenda eval() ocenia funkcje JavaScript na serwerze bazy danych i wyjaśnia() func. pokaż więcej informacji (w tym adres IP klastra (serwera) realnego wykonania) na temat wykonania kwerendy. Jeśli potrzebujesz odpowiednika funkcji findOne(), nadal możesz użyć filtru z funkcją find(), aby uzyskać tylko jeden dokument w wyniku. –