時系列をMongoDBに保存していますが、構造は次のとおりです。
{
"_id" : ObjectId("5128e567df6232180e00fa7d"),
"values" : [563.424, 520.231, 529.658, 540.459, 544.271, 512.641, 579.591, 613.878, 627.708, 636.239, 672.883, 658.895, 646.44, 619.644, 623.543, 600.527, 619.431, 596.184, 604.073, 596.556, 590.898, 559.334, 568.09, 568.563],
"day" : 20110628,
}
values-array は、各時間の値を表しています。そのため、 position0 = first hour
など1 = second hour
と同様に重要です。
特定の時間の値を更新するのは非常に簡単です。たとえば、1 日の 7 時間を更新するには、次のようにします。
db.timeseries.update({day:20130203},{$set : {values.6 : 482.65}}, {upsert : true})
私の問題は、このようにupsertを使用したいということです
db.timeseries.update({day:20130203},{$set : {values.6 : 482.65}})
しかし、ドキュメントが存在しない場合、MongoDB は埋め込み配列ではなく埋め込みドキュメントを作成します。このような:
{
"_id" : ObjectId("5128e567df6232180e00fa7d"),
"values" : {"6" : 482.65},
"day" : 20130203,
}
この問題を解決する機能を追加するためのチケットがここにありますが、その間、私の場合はこれを解決するための回避策を考え出しました。
私がしていることは、最初に day-field に uniqe-index を作成したことです。そして、1 時間ごとのボリュームをアップサートするときはいつでも、次の 2 つのコマンドを実行します。
db.timeseries.insert({day:20130203, values : []}); // Will be rejected if it exists
db.timeseries.update({day:20130203},{$set : {values.6 : 482.65}});
最初のステートメントは新しいドキュメントを作成しようとしました - uniqe-index のおかげで、挿入が既に存在する場合は拒否されます。そうでない場合は、value-field の配列が埋め込まれたドキュメントが作成されます。これにより、更新が確実に機能します。
結果:
{
"_id" : ObjectId("5128e567df6232180e00fa7d"),
"values" : [null,null,null,null,null,null,482.65],
"day" : 20130203,
}
そして、これが私の質問です
本番環境で、このような複数のコマンドが同時に実行される場合、挿入コマンドの後に更新コマンドが実行されることを確認できますか? 両方のコマンドをアンセーフ モードで実行したいことに注意してください。つまり、サーバーからの応答を待ちません。
(パフォーマンスの観点から、私の回避策についてここにコメントすることも興味深いでしょう。)