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

Węzeł wstawia duże dane za pomocą mangusty

Problem polega na tym, że uruchomiona pętla nie czeka na zakończenie każdej operacji. W rzeczywistości po prostu czekasz w kolejce 1000 .save() żądań i próbując je uruchomić jednocześnie. Nie możesz tego zrobić w rozsądnych granicach, dlatego otrzymasz odpowiedź na błąd.

async moduł ma różne metody iteracji podczas przetwarzania wywołania zwrotnego dla tego iteratora, przy czym prawdopodobnie najprostszym bezpośrednim dla jest podczas . Mongoose obsługuje również zarządzanie połączeniem bez konieczności osadzania w wywołaniu zwrotnym, ponieważ modele są świadome połączenia:

var tempColSchema = new Schema({
    cid: {
        type: Number,
        required: true
    },
    loc:[]
});

var TempCol = mongoose.model( "TempCol", tempColSchema );

mongoose.connect( 'mongodb://localhost/mean-dev' );

var i = 0;
async.whilst(
    function() { return i < 10000000; },
    function(callback) {
        i++;
        var c = i;
        console.log(c);
        var lon = parseInt(c/100000);
        var lat = c%100000;
        new Tempcol({cid: Math.random(), loc: [lon, lat]}).save(function(err){
            callback(err);
        });            
    },
    function(err) {
       // When the loop is complete or on error
    }
);

Nie jest to najbardziej fantastyczny sposób na zrobienie tego, wciąż jest to jeden zapis na raz i można użyć innych metod do "zarządzania" współbieżnymi operacjami, ale to przynajmniej nie rozwali stosu wywołań.

Z MongoDB w wersji 2.6 lub nowszej możesz skorzystać z Interfejsu API operacji zbiorczych w celu jednoczesnego przetwarzania więcej niż jednego zapisu na serwerze. Proces jest więc podobny, ale tym razem możesz wysłać 1000 naraz do serwera w jednym zapisie i odpowiedzi, co jest znacznie szybsze:

var tempColSchema = new Schema({
    cid: {
        type: Number,
        required: true
    },
    loc:[]
});

var TempCol = mongoose.model( "TempCol", tempColSchema );

mongoose.connect( 'mongodb://localhost/mean-dev' );

mongoose.on("open",function(err,conn) {

    var i = 0;
    var bulk = TempCol.collection.initializeOrderedBulkOp();

    async.whilst(
      function() { return i < 10000000; },
      function(callback) {
        i++;
        var c = i;
        console.log(c);
        var lon = parseInt(c/100000);
        var lat = c%100000;

        bulk.insert({ "cid": Math.random(), "loc": [ lon, lat ] });

        if ( i % 1000 == 0 ) {
            bulk.execute(function(err,result) {
                bulk = TempCol.collection.initializeOrderedBulkOp();
                callback(err);
            });
        } else {
            process.nextTick(callback);
        }
      },
      function(err) {
        // When the loop is complete or on error

        // If you had a number not plainly divisible by 1000
        if ( i % 1000 != 0 )
            bulk.execute(function(err,result) {
                // possibly check for errors here
            });
      }
    );

});

W rzeczywistości używa się natywnych metod sterownika, które nie są jeszcze widoczne w manguście, więc dokłada się dodatkowej staranności, aby upewnić się, że połączenie jest dostępne. To przykład, ale nie jedyny sposób, ale głównym punktem jest to, że mangusta „magia” połączeń nie jest tutaj wbudowana, więc powinieneś być pewien, że została ustanowiona.

Masz okrągłą liczbę elementów do przetworzenia, ale jeśli tak nie jest, powinieneś wywołać bulk.execute() w tym ostatnim bloku, jak pokazano, ale zależy to od liczby odpowiadającej modulo.

Najważniejsze jest, aby nie powiększać stosu operacji do nierozsądnych rozmiarów i ograniczać przetwarzanie. Sterowanie przepływem w tym miejscu umożliwia operacje, których faktyczne zakończenie zajmie trochę czasu przed przejściem do następnej iteracji. Tak więc aktualizacje wsadowe lub dodatkowe równoległe kolejkowanie są tym, czego potrzebujesz, aby uzyskać najlepszą wydajność.

Istnieje również .initializeUnorderedBulkOp() dla tego formularza, jeśli nie chcesz, aby błędy zapisu były krytyczne, ale zamiast tego obsługuj je w inny sposób. Zapoznaj się głównie z oficjalną dokumentacją dotyczącą Bulk API i odpowiedziami, jak interpretować udzieloną odpowiedź.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Zrozumienie opcji tworzenia kopii zapasowych MongoDB

  2. Modelowanie danych MongoDB:jakiekolwiek wady korzystania z wielu baz danych?

  3. Sterownik MongoDB-Java:Złap wyjątek, gdy wstawienie nie powiedzie się

  4. Gniazdo listonosza rozłączyło się, nie mogło połączyć się z Mongodb

  5. Zapytanie, aby uzyskać wartość, odejmując wartość z bieżącego i następnego dokumentu