我正在将MongoDb Scala连接器用于Spark。在文档中 https://docs.mongodb.com/spark-connector/master/scala/aggregation/
提到了如何在给定的JSON文档上应用过滤器。我无法弄清楚的是,如果我们有一个多层json并想对其应用过滤器,我们将如何访问json文档中的键/值。
Json文档:
{ "_id" : 1, "test" : 1 }
{ "_id" : 2, "test" : 2 }
{ "_id" : 3, "test" : 3 }
{ "_id" : 4, "test" : 4 }
{ "_id" : 5, "test" : 5 }
{ "_id" : 6, "test" : 6 }
过滤文档:
val rdd = MongoSpark.load(sc)
val filteredRdd = rdd.filter(doc => doc.getInteger("test") > 5)
println(filteredRdd.count)
println(filteredRdd.first.toJson)
多层Json文档
{
"_id": 1,
"test": 1,
"additionalProperties": {
"value": "35",
"phone": "566623232"
}
}
问题陈述:
我想基于“值”属性进行过滤,但是我不知道如何访问它。我尝试执行以下操作,但无法正常工作。
val filteredRdd = rdd.filter(doc => doc.getInteger("value") > 5)
val filteredRdd = rdd.filter(doc => doc.getInteger("additionalProperties.value") > 5)
有人可以指导我如何访问“值”属性吗?什么是正确的语法。
我尝试过的其他一些选项:
根据Scala Connector for MongoDB的官方文档。我尝试使用聚合管道过滤文档。因此以下代码行可以正常工作:
val filterWithPipeline = customRdd.withPipeline(Seq(Document.parse("{ $match: { id: { $eq : '134' } } }")))
但是,如果我想使用相同的语法访问“值”项。没用
val filterWithPipeline = customRdd.withPipeline(Seq(Document.parse("{ $match: { value: { $eq : '134' } } }")))
那么我该如何使用相同的方法来查询多级JSON?
答案 0 :(得分:1)
如果使用dafaframe,该怎么办?
val df = spark.read.json("path")
这是我的例子,
+---+--------------------+----+
|_id|additionalProperties|test|
+---+--------------------+----+
|1 |[566623232, 35] |1 |
|2 |[566623232, 35] |2 |
|3 |[566623232, 1] |3 |
+---+--------------------+----+
架构是
root
|-- _id: long (nullable = true)
|-- additionalProperties: struct (nullable = true)
| |-- phone: string (nullable = true)
| |-- value: string (nullable = true)
|-- test: long (nullable = true)
然后
df.filter(col("additionalProperties").getItem("value").cast("int") > 5)
将给出如下结果:
+---+--------------------+----+
|_id|additionalProperties|test|
+---+--------------------+----+
|1 |[566623232, 35] |1 |
|2 |[566623232, 35] |2 |
+---+--------------------+----+
答案 1 :(得分:1)
以下是您可以从mongoDB中读取并过滤它的几种方法 创建SparkSession
val spark = SparkSession.builder().master("local").appName("Test")
.config("spark.mongodb.input.uri", "mongodb://127.0.0.1/db.collectionName")
.config("spark.mongodb.output.uri", "mongodb://127.0.0.1/db.CollectionName")
.getOrCreate
import spark.implicits._
import com.mongodb.spark.sql._
读取为MongoRDD[Document]
并对其进行过滤
MongoSpark.load(spark.sparkContext).filter(doc => {
val value = doc.get("additionalProperties").asInstanceOf[Document].get("value")
value.toString.toInt > 5
})
通过spark.read.mongo()读为Dataframe
val filterDF = spark.read.mongo().filter($"additionalProperties.value".lt(5))
输出:
+---+--------------------+----+
|_id|additionalProperties|test|
+---+--------------------+----+
|2.0|[5, 566623232] |2.0 |
+---+--------------------+----+
希望这会有所帮助!