sql >> データベース >  >> NoSQL >> MongoDB

マングースは1つを見つけて、ドキュメントの配列にプッシュします

    基本的に、 $ addToSetを配置します データが真の" set" ではないため、オペレーターはあなたのために働くことができません 定義上、「完全に異なる」オブジェクトのコレクションです。

    ここでのもう1つの論理的な意味は、データが到着したときに、単一のオブジェクトまたはフィードとしてデータを処理することです。何らかの形で多くのアイテムのフィードがあり、受信したドキュメントごとにこの構造に到達するために、ある種のストリームプロセッサを使用できると想定します。

    {
        "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
    }
    

    もちろん、データストアからデータを取得した後は、ロケール設定をアプリケーションのドメインにする必要があるため、標準の10進形式とUTC日付に変換します。

    また、他のコレクションへの参照を削除し、そこにデータを配置することで、少なくとも「intraDayQuoteSchema」を少しフラットにします。挿入時にルックアップが必要ですが、読み取り時の追加の入力のオーバーヘッドは、ストレージのオーバーヘッドよりもコストがかかるようです:

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

    使用パターンにもよりますが、その方が効果的である可能性があります。

    残りは本当に許容できるものに帰着します

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

    応答で変更されたドキュメントが実際に必要ない場合は、ここにBulk Operations APIを実装し、このパッケージのすべての更新を1つのデータベースリクエスト内に送信することで、いくつかのメリットが得られます。

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

    重要なのは、そこにあるステートメントの1つだけが実際にデータを変更し、これはすべて同じリクエストで送信されるため、アプリケーションとサーバーの間のやり取りが少なくなるということです。

    別のケースは、この場合、実際のデータを別のコレクションで参照する方が簡単な場合があります。これは、アップサートを処理するという単純な問題になります。

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

    見積もりの​​データを「日」ドキュメント内にネストすることが、あなたにとってどれほど重要かということです。主な違いは、これらの「引用」フィールドの一部のデータに基づいてこれらのドキュメントをクエリするか、それ以外の場合は .populate()を使用するオーバーヘッドを伴うかどうかです。 他のコレクションから「引用符」を取得します。

    もちろん、参照されており、見積もりデータがクエリフィルタリングにとって重要である場合は、いつでもそのコレクションに _idをクエリできます。 $ in 「日」ドキュメントをクエリして、一致した「見積もり」ドキュメントを含む日のみに一致させます。

    アプリケーションがデータをどのように使用するかに基づいて、どのパスを選択するかが最も重要になるのは大きな決断です。うまくいけば、これはあなたが達成したいことをすることの背後にある一般的な概念についてあなたを導くはずです。

    P.Sソースデータが常に正確な「分」に丸められた日付であることが「確実」でない限り、離散的な「日」を取得するために使用されるのと同じ種類の日付丸め計算を使用することをお勧めします。

    >


    1. mongodbドキュメントのすべての配列要素を特定の値に変更するにはどうすればよいですか?

    2. 1つのコレクションのすべてのドキュメントで一意の値を持つ配列

    3. MongoDB:自動生成されたIDはゼロです

    4. シャードキーなしのすべてのシャードコレクションに対するMongoDBクエリ