MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

Insertion de nouveaux champs (colonnes) dans mongoDB avec pandas

La méthode dont vous avez besoin est update_one() avec upsert=True en boucle; vous ne pouvez pas utiliser insert_many() pour deux raisons; premièrement, vous n'insérez pas toujours ; parfois vous mettez à jour ; deuxièmement update_many() (et insert_many() ) ne fonctionne que sur un seul filtre ; dans votre cas, chaque filtre est différent car chaque mise à jour se rapporte à une heure différente.

Il s'agit d'une solution générique qui combinera des dataframes (df_a , df_b dans ce cas - vous pouvez en avoir autant que vous le souhaitez) de la manière dont vous avez besoin. Il utilise iterrows pour obtenir chaque ligne de la trame de données, filtre sur la date et définit les valeurs sur celles de la trame de données. le $set l'opérateur remplacera les valeurs si elles sont déjà présentes et les définira si elles ne sont pas définies. upsert=True effectuera une insertion s'il n'y a pas de correspondance à la date.

for df in [df_a, df_b]:
    for _, row in df.iterrows():
        db.mycollection.update_one({'date': row.get('date')}, {'$set': row.to_dict()}, upsert=True)

Exemple complet :

from pymongo import MongoClient
from pprint import pprint
import datetime
import pandas as pd

# Sample data setup

db = MongoClient()['mydatabase']

data_a = [[datetime.datetime(2017, 5, 19, 21, 20), 96, 8, 98],
          [datetime.datetime(2017, 5, 19, 21, 21), 95, 8, 97],
          [datetime.datetime(2017, 5, 19, 21, 22), 95, 8, 97]]

df_a = pd.DataFrame(data_a, columns=['date', 'std_500_1000window', 'std_50_100window', 'std_50_2000window'])

data_b = [[datetime.datetime(2017, 5, 19, 21, 20), 98, 9, 10],
          [datetime.datetime(2017, 5, 19, 21, 21), 98, 9, 10],
          [datetime.datetime(2017, 5, 19, 21, 22), 98, 9, 10]]

df_b = pd.DataFrame(data_b, columns=['date', 'std_50_3000window', 'std_50_300window', 'std_50_500window'])

# Perform the upserts

for df in [df_a, df_b]:
    for _, row in df.iterrows():
        db.mycollection.update_one({'date': row.get('date')}, {'$set': row.to_dict()}, upsert=True)

# Print the results

for record in db.mycollection.find():
    pprint(record)

Résultat :

{'_id': ObjectId('5f0ae909df5531ac655ce528'),
 'date': datetime.datetime(2017, 5, 19, 21, 20),
 'std_500_1000window': 96,
 'std_50_100window': 8,
 'std_50_2000window': 98,
 'std_50_3000window': 98,
 'std_50_300window': 9,
 'std_50_500window': 10}
{'_id': ObjectId('5f0ae909df5531ac655ce52a'),
 'date': datetime.datetime(2017, 5, 19, 21, 21),
 'std_500_1000window': 95,
 'std_50_100window': 8,
 'std_50_2000window': 97,
 'std_50_3000window': 98,
 'std_50_300window': 9,
 'std_50_500window': 10}
{'_id': ObjectId('5f0ae909df5531ac655ce52c'),
 'date': datetime.datetime(2017, 5, 19, 21, 22),
 'std_500_1000window': 95,
 'std_50_100window': 8,
 'std_50_2000window': 97,
 'std_50_3000window': 98,
 'std_50_300window': 9,
 'std_50_500window': 10}