Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Apache spark PySpark MongoDB从DataFrame追加数组的所有元素_Apache Spark_Pyspark_Spark Dataframe_Pymongo_Pyspark Sql - Fatal编程技术网

Apache spark PySpark MongoDB从DataFrame追加数组的所有元素

Apache spark PySpark MongoDB从DataFrame追加数组的所有元素,apache-spark,pyspark,spark-dataframe,pymongo,pyspark-sql,Apache Spark,Pyspark,Spark Dataframe,Pymongo,Pyspark Sql,我有一个MongoDB集合,看起来像这样: { "_id" : { "customerName" : "Bob", "customerPhone" : "123-456-7890"}, "purchases": ["A", "B", "C", "D"] } 基本上_id是一对关于客户的唯一密钥,购买是客户购买的物品的数组 我也有一个PySpark数据框架,我想把它推到这个集合中,其中包含我想更新这个特定文档的信息 df.write.format("com.mongodb.sp

我有一个MongoDB集合,看起来像这样:

{
    "_id" : { "customerName" : "Bob",  "customerPhone" : "123-456-7890"},
    "purchases": ["A", "B", "C", "D"]
}
基本上_id是一对关于客户的唯一密钥,购买是客户购买的物品的数组

我也有一个PySpark数据框架,我想把它推到这个集合中,其中包含我想更新这个特定文档的信息

df.write.format("com.mongodb.spark.sql.DefaultSource").mode("append") \
                .option("spark.mongodb.output.uri", "mongodb://localhost:27017/customer.purchases").save()
问题是,如果我更新此文档,希望为Bob添加新的采购,它将只在
purchases
中追加不存在的采购,而不是追加所有采购

因此,我现在要做的就是调用
rdd.collect()
将整个内容转换为一个列表,而不是使用模式将其转换为DataFrame。然后逐个插入所有内容,同时检查密钥是否存在;这使得这部分速度变慢,并且在RDD查询变大时需要大量内存

对于版本:

Pypark:2.2 MongoDB:3.0.15 Mongo火花连接器:2.2.1

如果我可以使用dataframe将数组中的所有元素附加到MongoDB集合中,是否有人知道我可以做些什么? 另外,如果我有什么遗漏或其他我应该做的事情,请告诉我。 谢谢

您需要更改文档的格式或架构。这里的重要部分是
\u id
键字段。字段名
\u id
保留用作主键;它的值在集合中必须是唯一的、不可变的,并且可以是数组以外的任何类型

在您的例子中,
\u id
字段的值是可变的,实际上这就是您要更新的内容。建议您将此更改为:

{ "_id" : <unique identifier>
  "customerName" : "Bob",  
  "customerPhone" : "123-456-7890",
  "purchases": ["A", "B", "C", "D"]
}
{“\u id”:
“客户名称”:“鲍勃”,
“客户电话”:“123-456-7890”,
“采购”:[“A”、“B”、“C”、“D”]
}
您可以使用的默认
\u id
值作为唯一标识符

一旦您在
\u id
字段上有了唯一的标识符,我们来谈谈更新操作。从v1.1+(当前版本为2.2)开始,如果数据帧在写入期间包含
\u id
字段,则数据将被删除。这意味着将更新具有相同_id值的任何现有文档,并插入集合中没有现有_id值的新文档

奖金回合:

  • 您还需要为
    购买
    字段找到更好的模式。具有未定义长度的数组长度可能会在将来产生问题。i、 鲍勃一年买了1000件

  • 请更新您的MongoDB服务器版本(版本3.0.x从2015年开始),当前稳定的版本是3.4,3.6将在下个月发布


谢谢您的回复。对于我的用例,我可以保证
customerName
customerPhone
始终是唯一的密钥对。使用ObjectID时也很难找到
\u id
,因为找到它还需要额外的一步,而且将所有数据从工作节点收集到主节点的成本很高。您知道还有其他方法吗?如果您遵循上面的示例模式,您仍然可以使用
customerName
customerPhone
或两者都使用来查询记录。这也适用于您的MongoDB Spark upsert
\u id
保留为唯一的主键,如果要在
\u id
中存储子文档,则必须按该顺序提供这两个字段。我建议考虑一下你的模式。另请参阅及