2017-10-18 8 views
1

J'essaie d'obtenir un retour avec les dernières valeurs/les plus récentes pour chaque $ src, mais aussi obtenir un 30 jours $ min et $ max sur le champ # pouces. Voir la requête ci-dessousMongoDB Agréger les derniers enregistrements et faire correspondre certains champs à 30 jours

 date = datetime.datetime.today() - datetime.timedelta(days=31) 

     last_data = collection.aggregate([ 
     {"$group": {"_id": "$src", 
        "date": {"$last": "$time"}, 
        "inches": {"$last": "$inches"}, 
        "low":{"$min":"$inches"}, 
        "high":{"$max":"$inches"} 
        } } 
    ]) 

Cela fonctionne bien, sauf que les bas et haut sont toujours à jamais bas et haut. Je veux restreindre le bas et le haut pour ne tirer que dans les 30 derniers jours. Utilisation de l'objet datetime timedelta si possible. Vous trouverez ci-dessous un exemple de retour de toutes les données à partir d'une date donnée. Ce que je ne suis pas sûr de savoir comment faire est de combiner les deux requêtes en une seule.

 data = collection.find({'time':{ "$gte" : (date) }}) 

MISE À JOUR 1: Essayer le code ci-dessous sur ...

Note: La date est temps epoch 30 jours aujourd'hui = 1508360994,741111 date = 1505682594,741111

collection.aggregate([ 
     {"$group": {"_id": "$src", 
        "date": {"$last": "$time"}, 
        "inches": {"$last": "$inches"}, 
        "low": { 
         "$min": { 
          "$cond": [ 
           {"time": {"$lte": ["$time", date]}}, 
           "$inches", 
           None 
          ] 
         } 
        }, 
        "high": { 
         "$max": { 
          "$cond": [ 
           {"time": {"$gte": ["$time", date]}}, 
           "$inches", 
           None 
          ] 
         } 
        }, 
        }} 
    ]) 

I obtenir un retour comme ceci: Il semble donc que cela pourrait fonctionner. Je dois faire quelques vérifications de santé mentale pour m'assurer. {'_id': 'c4028504', 'date': datetime.datetime (2017, 10, 16, 2, 47, 21, 939000), 'pouces': 85.0, 'faible': 0, 'haut': 2007.25 },

Comment ajouteriez-vous une 2ème condition pour montrer seulement les bas> 0. Voir mon essai en lambeaux ci-dessous.

    "low": { 
         "$min": { 
          "$cond": [ { "$and" : [ 
           { "time": {"$gte": ["$time", date] }, 
           { "inches": {"$gt": ["$inches", 0] } 
           ]}, 
           "$inches", 
           None 
          ]} 
         } 
        }, 
+0

Pourriez-vous poster des échantillons de données? – dnickless

Répondre

1

Les deux min & max ignorer les valeurs nulles et manquantes en comparaison lorsque toutes les valeurs ne sont pas nulles ou manquantes.

Vous pouvez utiliser l'idée ci-dessus pour créer une requête ci-dessous.

"aujourd'hui" est la valeur utc de datetime et "date" est le delta en millisecondes. (ex: 30 * 86400 * 1000 pendant 30 jours).

Essentiellement utiliser l'opérateur conditionnel, calculer la diff entre $time et « aujourd'hui » et de comparer pour voir si la différence est inférieure à la valeur d'entrée (en millisecondes) puis $inches autre null.

"low": { 
    "$min": { 
    "$cond": [ 
     { 
     "$lte": [ 
      { 
      "$subtract": [ 
       "$time", 
       today 
      ] 
      }, 
      date 
     ] 
     }, 
     "$inches", 
     null 
    ] 
    } 
} 

Vous pouvez appliquer une logique similaire pour $max (haut) et d'ajuster la réponse pour python.

+0

J'ai mis à jour mon OP avec ma tentative d'implémentation du code que vous avez fourni. Une idée pourquoi je récupère les mêmes résultats pour le bas et le haut? Désolé je suis encore assez nouveau pour mongo essayant d'obtenir mes jambes venant de sql. –

+0

Pas de soucis. Votre syntaxe est incorrecte. Essayez ' "bas": { "min $": { "$ cond": [{ "$ lte": [ "$ time", date]}, "$ pouces", Aucun ] } } ' – Veeram

+0

J'ai mis à jour mon OP avec, ce que je ne comprends pas c'est pourquoi c'est <= and not > = si je dis que je veux toutes les données dans les 30 derniers jours et je dis cond est> 30 jours en arrière, ne donnerait pas = moi avant les 30 jours? –