2017-09-09 11 views
1

数日前に私のコンピュータにMongoDBをインストールして仕事をテストしました。詳細には、PostgresベースのシステムからMongoDBに大量のデータを転送する必要があります。 私たちはMongoDBを初めて知ったので、私たちはドキュメントを勉強しようとしましたが、パフォーマンスをテストするために少数のDBでいくつかのテストを行いました... 今回は多くのテストの後、悪化する... しかし、今私は文脈を説明し、誰かが私たちに何か間違っているかどうか教えてもらえるかもしれません。 私たちは、より多くの「問題」のクエリである知っていると私はPostgresの中でクエリは、このような何か(私は不要にカットします)で、ここではそのうちの一つを書いてます:MongoDB最適化アグリゲーション

selectStmt varchar = 'SELECT station.radarmeteo_id, 
    date(datetime_range) AS datetime_range, 
    district.name AS district, 
    city.name AS city, 
    min_temperature::real/10::real, 
    max_temperature::real/10::real, 
    rainfall_daily::real/10::real, 
    max_wind_speed::real/10::real, 
    extract(epoch FROM datetime_range) as unix_datetime '; 

fromStmt varchar = ' FROM measurement_daily 
    INNER JOIN station ON measurement_daily.station_id = station.id; 

をMongoDBのでは、我々はこれを書きました:

db.measurement_daily.aggregate([{"$match":{"min_temperature":{"$gt":random.randint(-30, 14), "$lt":random.randint(18, 50)}}},{"$lookup":{"from":"station","localField":"station_id", "foreignField":"_id", "as": "scd"}},{"$unwind":"$scd"},{"$project":{"_id":1,"min_temperature":1,"max_temperature":1, "rainfall_daily":1, "max_wind_speed":1, "radarmeteo_id":"$scd.radarmeteo_id", "city_name":"$scd.city_name", "district_name":"$scd.district_name"}},{"$out":"result"}]) 

ここで私が求めているのは、より良く書かれていますか?あるいは、同じ結果を得るためのより良い方法があるかもしれませんか?他にも最適化がありますか? 実際のDBはこのコレクション内のデータの200.000.000のようなものを持つ必要があるため、最善の応答時間が必要です。 1000(ステーション)と6400(measurement_daily)のレコード/ドキュメントをそれぞれ2つ含むテーブル応答時間として3,5-4s(Postgres)vs 30-32s(MongoDB)を持っています... (両方のシステムでパフォーマンスをテストするために、クエリは200回繰り返されます(3,5-4,30外部要因によるコンディショニングを最小限にするために、「均質」の応答時間を持っているそれぞれ1つのクエリの-32s)。) $のアンワインドがすぐに別の$検索を以下の場合はすべてのヘルプは本当にmongoDB documentationによると...

答えて

2

を高く評価されており、 $ unwindは$ルックアップのasフィールドで動作し、オプティマイザは$ unwindを合体させることができます$ルックアップステージに移動します。これにより、大きな中間ドキュメントを作成することがなくなります。

"$lookup": { 
    "from":"station", 
    "localField":"station_id", 
    "foreignField":"_id", 
    "as": "scd" 
    unwinding: { preserveNullAndEmptyArrays: false } 
} 

あなたのケースでは、それは次のようになります