2017-09-09 3 views
1

J'ai installé il ya quelques jours MongoDB sur mon ordinateur pour faire un test pour un travail, en détail, nous devons transférer une énorme quantité de données d'un système basé sur Postgres à un MongoDB. Parce que nous ne connaissons pas MongoDB (la première fois que nous l'utilisons) nous avons essayé d'étudier la documentation et nous avons fait quelques tests sur un petit DB avec peu de données pour tester la performance ... une aggravation ... Cependant maintenant je vais expliquer le contexte alors peut-être quelqu'un pourrait me dire si nous avons fait quelque chose de mal ou non. Nous savons qui sont les plus « problématiques » questions et j'écrit ici un d'entre eux, dans Postgres la requête est quelque chose comme ça (je coupe le nécessaire):MongoDB optimisation agrégation

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; 

En MongoDB nous avons écrit ceci:

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"}]) 

Ce que je demande ici est: il devrait être écrit mieux? Ou il pourrait y avoir une meilleure façon d'avoir le même résultat? Y a-t-il d'autres optimisations que nous pouvons utiliser? Nous avons besoin du meilleur temps de réponse parce que la vraie DB devrait avoir quelque chose comme 200.000.000 de données seulement dans cette collection ... Et juste ici avec 2 tables avec 1000 (station) et 6400 (mesure_daily) dossiers/documents respectivement, nous avoir 3,5-4s (Postgres) vs 30-32s (MongoDB) comme temps de réponse ... (Pour tester la performance dans les deux systèmes la requête est répétée 200 fois (c'est pourquoi nous avons 3,5-4 et 30 -32s pour une requête respectivement) pour avoir un temps de réponse "homogène" pour minimiser le conditionnement par des causes externes.) Toute aide est vraiment appréciée ...

Répondre

2

Selon mongoDB documentation Quand un déroulement $ suit immédiatement une autre recherche $, et le $ unwind fonctionne sur le champ as de la recherche $, l'optimiseur peut fusionner le $ déroulant dans la phase de recherche $. Cela évite de créer de gros documents intermédiaires.

Dans votre cas, il ressemblera:

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