我有一个包含26,000条记录的MongoDB集合,我正在读取一个DataFrame。它在所有记录中都有一个column_1
列,字符串值为column_1_value
。我正在尝试过滤DataFrame并按如下方式获取计数
val readConfig = ReadConfig(Map("collection" -> collectionName,"spark.mongodb.input.readPreference.name" -> "primaryPreferred", "spark.mongodb.input.database" -> dataBaseName, "spark.mongodb.input.uri" -> hostName))
val dataFrame = MongoSpark.load(spark, readConfig)
df.filter(df.col("column_1") === "column_1_value").count()
其中spark
是SparkSession
的实例。
MongoDB记录结构看起来像这样。
{
"_id" : ObjectId("SOME_ID"),
"column_1" : "column_1_value",
"column_2" : SOME_VALUE,
"column_3" : SOME_OTHER_VALUE
}
没有嵌套结构,并且所有记录都具有相同的字段集。我在Spark正在运行的任何时候都没有访问数据库
由于所有记录都具有column_1
的相同值,我希望将DataFrame大小本身作为输出,但我得到的值更低。不仅如此,每次运行上述内容时,我都会得到不同的结果。结果通常在15,000到24,000之间变化。
但是当收集尺寸小于5,000时,同样的方法似乎也有效。
我尝试了以下方法但没有成功
equalTo
代替===
$column_1
isin
df.where
代替df.filter
createOrReplaceTempView
并运行SQL查询唯一可行的是df.cache()
或df.persist()
,我认为在处理大数据时,这些都不会对整体效果有所帮助。
这种行为的可能原因以及解决方法可能是什么原因?
我的Spark版本是2.2.0,MongoDB版本是3.4。我在本地模式下运行Spark,具有16 GB的RAM和8核处理器。
尝试按如下方式更改Mongo Spark连接器分区策略,但没有成功。
val readConfig = ReadConfig(Map("collection" -> collectionName,"spark.mongodb.input.readPreference.name" -> "primaryPreferred", "spark.mongodb.input.database" -> dataBaseName, "spark.mongodb.input.uri" -> hostName, "spark.mongodb.input.partitionerOptions" -> "MongoPaginateBySizePartitioner"))
val dataFrame = MongoSpark.load(spark, readConfig)
df.count()
df.filter(df.col("column_1") === "column_1_value").count()
第一个计数返回正确的值,即使使用默认的分区策略,这也让我相信Mongo Connector工作正常。