簡體   English   中英

在pyspark Dataframe上進行迭代,然后針對每一行與mongoDB進行交互

[英]iterate over pyspark Dataframe and then for each row interact with mongoDB

我有一個pyspark數據框,現在我想遍歷每行並插入/更新到mongoDB集合。

 #Did every required imports 
 #dataframe
 +---+----+
 |age|name|
 +---+----+
 | 30|   c|
 |  5|   e|
 |  6|   f|
 +---+----+
  db = mongodbclient['mydatabase']
  collection = db['mycollection']
  #created below function to insert/update
  def customFunction(row):
      key = {'name':row.name}
      data = dict(zip(columns,[row.x for x in columns]))
      collection.update(key, data, {upsert:true})
      #return a_flag #commented it as of now, a_flag can be 0 or 1

如果mongoDB集合“ mycollection”中存在名稱,則應更新該行/記錄,否則插入該新記錄。

嘗試在spark-dataframe上映射此功能時出現以下錯誤

 result = my_dataframe.rdd.map(customFunction)
 #.....TypeError: can't pickle _thread.lock objects....
 #AttributeError: 'TypeError' object has no attribute 'message'

任何人都可以找出“該功能和/或其他任何地方在哪里出問題了”,或者請提出是否有其他替代方法來解決此類任務。

基本上迭代每行(甚至沒有可能進行collect調用嗎?)

並且,在每一行上應用一個功能來運行外部火花工作。

請建議,在此先謝謝.. :)

我在mongoDB中的數據

name  age
 a    1
 b    2
 c    3 #new update should make age as 30 and 2 more new recs should inserted

似乎無法腌制連接對象。 我會用foreachPartition

def customFunction(rows):
    db = mongodbclient['mydatabase']
    collection = db['mycollection']

    for row in rows:
        key = {'name':row.name}
        data = dict(zip(columns,[row.x for x in columns]))
        collection.update(key, data, {upsert:true})

my_dataframe.rdd.foreachPartition(customFunction)

但是請記住,致命故障可能會使數據庫處於不一致狀態。

如果您要在MongoDB中上傳50萬條記錄,則批量模式可能是處理此問題的更有效方法。 與您在spark中實際執行的操作(僅創建請求)相比,在mongoDB內部執行請求將需要更多的功能,即使並行執行此操作也可能導致mongo方面的不穩定(並且比“迭代”方法要慢)。

您可以嘗試以下代碼。 它不使用collect() ,因此在驅動程序上的內存效率很高:

bulk = collection.initialize_unordered_bulk_op()
for row in rdd.toLocalIterator():
    key = {'name':row.name}
    data = dict(zip(columns,[row.x for x in columns]))
    bulk.update(key, data, {upsert:true})

print(bulk.execute())

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM