filtre étincelle dataframe avec la ligne de champ qui est un tableau de chaînes de caractères

À l'aide de l'Étincelle de 1,5 et Scala 2.10.6

Je suis en train de filtrer un dataframe par l'intermédiaire d'un champ "tags" qui est un tableau de chaînes de caractères. Recherche de toutes les lignes qui ont le tag "privé".

val report = df.select("*")
  .where(df("tags").contains("private"))

:

Exception in thread "main" org.apache.spark.sql.AnalysisException:
ne peut pas résoudre "Contient(tags, privé)" en raison d'incompatibilité de type de données:
argument 1 exige de type chaîne de caractères, cependant, "tags" est de tableau
type.;

Est la méthode de filtrage mieux adapté?

Mise à JOUR:

les données proviennent de cassandra adaptateur, mais un minimum d'exemple qui montre ce que je suis en train de faire et aussi obtient l'erreur ci-dessus est:

  def testData (sc: SparkContext): DataFrame = {
    val stringRDD = sc.parallelize(Seq("""
      { "name": "ed",
        "tags": ["red", "private"]
      }""",
      """{ "name": "fred",
        "tags": ["public", "blue"]
      }""")
    )
    val sqlContext = new org.apache.spark.sql.SQLContext(sc)
    import sqlContext.implicits._
    sqlContext.read.json(stringRDD)
  }
  def run(sc: SparkContext) {
    val df1 = testData(sc)
    df1.show()
    val report = df1.select("*")
      .where(df1("tags").contains("private"))
    report.show()
  }

Mise à JOUR: les balises de tableau peut être n'importe quelle longueur et le "privé" de la balise peut être dans n'importe quelle position

Mise à JOUR: une solution qui fonctionne: UDF

val filterPriv = udf {(tags: mutable.WrappedArray[String]) => tags.contains("private")}
val report = df1.filter(filterPriv(df1("tags")))
post échantillon de vos données et comment u r de la création de la df
Une option est de construire un UDF.
Eh bien, après avoir regardé le code source (depuis le scaladoc pour Column.contains dit seulement "Contient l'autre" qui n'est pas très instructif), je vois que Column.contains construit une instance de org.apache.spark.sql.catalyst.expressions.Contains qui dit "Une fonction qui renvoie true si la chaîne left contient la chaîne de caractères right". Il semble donc que df1("tags").contains ne peut pas faire ce que nous voulons faire dans ce cas. Je ne sais pas quelle autre solution à proposer. Il y a un ArrayContains également dans ...expressions mais Column ne semble pas en faire usage.
En effet, après avoir changé les données à des chaînes au lieu d'un tableau de chaînes de caractères, je trouve que la requête fonctionne.
J'ai eu un UDF de travail: val filterPriv = udf {(tags: mutable.WrappedArray[String]) => tags.contains("private")}; val report = df1.filter(filterPriv(df1("tags"))) toujours à la recherche de quelque chose de plus sympa, mais au moins je ne suis pas bloqué. thx!

OriginalL'auteur navicore | 2016-01-17