MongoDB
 sql >> Teknologi Basis Data >  >> NoSQL >> MongoDB

Luwak temukan satu dan dorong ke berbagai dokumen

Pada dasarnya letakkan $addToSet operator tidak dapat bekerja untuk Anda karena data Anda bukan "set" yang sebenarnya menurut definisi adalah kumpulan objek yang "benar-benar berbeda".

Bagian lain dari pengertian logis di sini adalah bahwa Anda akan mengerjakan data saat tiba, baik sebagai objek tunggal atau umpan. Saya akan menganggapnya sebagai umpan dari banyak item dalam beberapa bentuk dan Anda dapat menggunakan semacam pemroses aliran untuk sampai pada struktur ini per dokumen yang diterima:

{
    "date": new Date("2015-03-09 13:23:00.000Z"),
    "symbol": "AAPL",
    "open": 127.14
    "high": 127.17,
    "low": 127.12 
    "close": 127.15,
    "volume": 19734
}

Mengonversi ke format desimal standar serta tanggal UTC karena setelan lokal apa pun harus benar-benar menjadi domain aplikasi Anda setelah data diambil dari penyimpanan data tentunya.

Saya juga akan sedikit meratakan "intraDayQuoteSchema" Anda dengan menghapus referensi ke koleksi lain dan hanya meletakkan data di sana. Anda masih memerlukan pencarian saat penyisipan, tetapi overhead dari populasi tambahan yang dibaca tampaknya akan lebih mahal daripada overhead penyimpanan:

intradayQuotesSchema = Schema({
    symbol:{
        name: String,
        code: String
    },
    day:Date,
    quotes:[quotesSchema]
});

Itu tergantung pada pola penggunaan Anda, tetapi kemungkinan akan lebih efektif seperti itu.

Sisanya benar-benar bermuara pada apa yang dapat diterima

stream.on(function(data) {

    var symbol = data.symbol,
        myDay = new Date( 
            data.date.valueOf() - 
                ( data.date.valueOf() % 1000 * 60 * 60 * 24 ));
    delete data.symbol;

    symbol.findOne({ "code": symbol },function(err,stock) {

        intraDayQuote.findOneAndUpdate(
            { "symbol.code": symbol , "day": myDay },
            { "$setOnInsert": { 
               "symbol.name": stock.name
               "quotes": [data] 
            }},
            { "upsert": true }
            function(err,doc) {
                intraDayQuote.findOneAndUpdate(
                    {
                        "symbol.code": symbol,
                        "day": myDay,
                        "quotes.date": data.date
                    },
                    { "$set": { "quotes.$": data } },
                    function(err,doc) {
                        intraDayQuote.findOneAndUpdate(
                            {
                                "symbol.code": symbol,
                                "day": myDay,
                                "quotes.date": { "$ne": data.date }
                            },
                            { "$push": { "quotes": data } },
                            function(err,doc) {

                            }
                       );    
                    }
                );
            }
        );    
    });
});

Jika Anda tidak benar-benar membutuhkan dokumen yang dimodifikasi dalam tanggapan, maka Anda akan mendapatkan beberapa manfaat dengan menerapkan API Operasi Massal di sini dan mengirimkan semua pembaruan dalam paket ini dalam satu permintaan basis data:

stream.on("data",function(data) {

    var symbol = data.symbol,
        myDay = new Date( 
            data.date.valueOf() - 
                ( data.date.valueOf() % 1000 * 60 * 60 * 24 ));
    delete data.symbol;

     symbol.findOne({ "code": symbol },function(err,stock) {
         var bulk = intraDayQuote.collection.initializeOrderedBulkOp();
         bulk.find({ "symbol.code": symbol , "day": myDay })
             .upsert().updateOne({
                 "$setOnInsert": { 
                     "symbol.name": stock.name
                     "quotes": [data] 
                 }
             });

         bulk.find({
             "symbol.code": symbol,
             "day": myDay,
             "quotes.date": data.date
         }).updateOne({
             "$set": { "quotes.$": data }
         });

         bulk.find({
             "symbol.code": symbol,
             "day": myDay,
             "quotes.date": { "$ne": data.date }
         }).updateOne({
             "$push": { "quotes": data }
         });

         bulk.execute(function(err,result) {
             // maybe do something with the response
         });            
     });
});

Intinya adalah bahwa hanya satu pernyataan di sana yang benar-benar akan mengubah data, dan karena ini semua dikirim dalam permintaan yang sama, maka bolak-balik antara aplikasi dan server lebih sedikit.

Kasus alternatifnya adalah mungkin lebih sederhana dalam kasus ini untuk memiliki data aktual yang dirujuk dalam koleksi lain. Ini kemudian menjadi masalah sederhana dalam memproses upser:

intradayQuotesSchema = Schema({
    symbol:{
        name: String,
        code: String
    },
    day:Date,
    quotes:[{ type: Schema.Types.ObjectId, ref: "quote" }]
});


// and in the steam processor

stream.on("data",function(data) {

    var symbol = data.symbol,
        myDay = new Date( 
            data.date.valueOf() - 
                ( data.date.valueOf() % 1000 * 60 * 60 * 24 ));
    delete data.symbol;

    symbol.findOne({ "code": symbol },function(err,stock) {
         quote.update(
            { "date": data.date },
            { "$setOnInsert": data },
            { "upsert": true },
            function(err,num,raw) {
                if ( !raw.updatedExisting ) {
                    intraDayQuote.update(
                        { "symbol.code": symbol , "day": myDay },
                        { 
                            "$setOnInsert": {
                                "symbol.name": stock.name
                            },
                            "$addToSet": { "quotes": data }
                        },
                        { "upsert": true },
                        function(err,num,raw) {

                        }
                    );
                }
            }
        );
    });
});

Ini benar-benar tergantung pada seberapa penting bagi Anda untuk memiliki data untuk kutipan yang bersarang di dalam dokumen "hari". Perbedaan utamanya adalah jika Anda ingin menanyakan dokumen-dokumen tersebut berdasarkan data beberapa bidang "kutipan" tersebut atau jika tidak, hidup dengan overhead menggunakan .populate() untuk menarik "kutipan" dari koleksi lainnya.

Tentu saja jika direferensikan dan data kutipan penting untuk pemfilteran kueri Anda, maka Anda selalu dapat menanyakan koleksi itu untuk _id nilai yang cocok dan menggunakan $in kueri pada dokumen "hari" untuk hanya mencocokkan hari yang berisi dokumen "kutipan" yang cocok.

Ini adalah keputusan besar yang paling penting jalur mana yang Anda ambil berdasarkan cara aplikasi Anda menggunakan data. Semoga ini dapat memandu Anda tentang konsep umum di balik melakukan apa yang ingin Anda capai.

P.S Kecuali Anda "yakin" bahwa data sumber Anda selalu berupa tanggal yang dibulatkan menjadi "menit" yang tepat, maka Anda mungkin ingin menggunakan jenis matematika pembulatan tanggal yang sama seperti yang digunakan untuk mendapatkan "hari" diskrit juga.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Kueri untuk mendapatkan data X menit terakhir dengan Mongodb

  2. pymongo mendapatkan E11000 duplikat indeks kesalahan kunci kesalahan pymongo

  3. Cara mengimpor data dari file CSV ke koleksi Meteor di sisi server

  4. Menyimpan skema dan fungsi formulir dalam Database

  5. Bagaimana cara mengembalikan nilai varian dari setiap produk jika produk tersebut merupakan varian?