Próbuję użyć SQL na ramce danych iskry. Ale ramka danych ma 1 wartość ma ciąg (co jest JSON jak struktury):Jak wyszukiwać w ramce danych, gdzie 1 pole StringType ma wartość json w Spark SQL
Uratowałem moich danych ramki do tabeli temp: TestTable
Kiedy zrobiłem desc:
col_name data_type
requestId string
name string
features string
ale dysponuje wartości jest json:
{"places":11,"movies":2,"totalPlacesVisited":0,"totalSpent":13,"SpentMap":{"Movie":2,"Park Visit":11},"benefits":{"freeTime":13}}
chcę tylko zapytać na TestTable gdzie totalSpent> 10. Czy niektóre mi powiedzieć jak to zrobić?
Mój plik JSON wygląda następująco:
{
"requestId": 232323,
"name": "ravi",
"features": "{"places":11,"movies":2,"totalPlacesVisited":0,"totalSpent":13,"SpentMap":{"Movie":2,"Park Visit":11},"benefits":{"freeTime":13}}"
}
funkcji jest ciągiem. Potrzebuję tylko TotalSpent w tym. Próbowałem z:
val features = StructType(
Array(StructField("totalSpent",LongType,true),
StructField("movies",LongType,true)
))
val schema = StructType(Array(
StructField("requestId",StringType,true),
StructField("name",StringType,true),
StructField("features",features,true),
)
)
val records = sqlContext.read.schema(schema).json(filePath)
Ponieważ każde żądanie ma jeden ciąg znaków JSON. Ale to daje mi błąd.
Kiedy próbowałem z
val records = sqlContext.jsonFile(filePath)
records.printSchema
pokazuje mi:
root
|-- requestId: string (nullable = true)
|-- features: string (nullable = true)
|-- name: string (nullable = true)
mogę wykorzystać parallelize wewnątrz StructField podczas tworzenia schematu? Próbowałem z:
I first tried with :
val customer = StructField("features",StringType,true)
val events = sc.parallelize(customer :: Nil)
val schema = StructType(Array(
StructField("requestId",StringType,true),
StructField("name", StructType(events, true),true),
StructField("features",features,true),
)
)
Daje mi to również błąd. Próbowałem też:
import net.liftweb.json.parse
case class KV(k: String, v: Int)
val parseJson = udf((s: String) => {
implicit val formats = net.liftweb.json.DefaultFormats
parse(s).extract[KV]
})
val parsed = records.withColumn("parsedJSON", parseJson($"features"))
parsed.show
This gives me :
<console>:78: error: object liftweb is not a member of package net
import net.liftweb.json.parse
Tried:
Próbowałem z:
val parseJson = udf((s: String) => {
sqlContext.read.json(s)
})
val parsed = records.withColumn("parsedJSON", parseJson($"features"))
parsed.show
ale znowu błędu.
Tried:
import org.json4s._
import org.json4s.jackson.JsonMethods._
val parseJson = udf((s: String) => {
parse(s)
})
val parsed = records.withColumn("parsedJSON", parseJson($"features"))
parsed.show
ale daje mi:
java.lang.UnsupportedOperationException: Schema for type org.json4s.JValue is not supported
at org.apache.spark.sql.catalyst.ScalaReflection$class.schemaFor(ScalaReflection.scala:153)
at org.apache.spark.sql.catalyst.ScalaReflection$.schemaFor(ScalaReflection.scala:29)
at org.apache.spark.sql.catalyst.ScalaReflection$class.schemaFor(ScalaReflection.scala:64)
at org.apache.spark.sql.catalyst.ScalaReflection$.schemaFor(ScalaReflection.scala:29)
To daje mi właściwego schematu (na podstawie odpowiedzi udzielonej przez zero323:
val extractFeatures = udf((features: String) => Try {
implicit val formats = DefaultFormats
parse(features).extract[Features]
}.toOption)
val parsed = records.withColumn("features", extractFeatures($"features"))
parsed.printSchema
Ale kiedy zapytanie:
val value = parsed.filter($"requestId" === "232323").select($"features.totalSpent")
value.show gives null
.
@ zero323: Cześć, ja poszedłem za pośrednictwem innej kwestii u odpowiedział, ale ja nie całkiem to rozumiem. Czy możesz mi wyjaśnić? Jestem bardzo nowy, by iskrzyć. – Swetha
Która część jest niewyraźna? Jest to długa odpowiedź pokazująca różne metody w zależności od wymagań i wersji. Czy rozważasz jakieś konkretne rozwiązanie? – zero323
@ zero323 Próbowałem z użyciem paralise na moim schemacie, ponieważ używam schematu, aby uzyskać inne wartości, więc wolę używać go w schemacie, ale daje błąd. Jestem skłonny do UDF do parsowania JSON, gdzie wspomniałeś o klasie przypadku KV (k: String, v: Int) Czy to ze względu na sposób sformatowania jego json? – Swetha