簡體   English   中英

Elasticsearch-Spark序列化不適用於內部類

[英]Elasticsearch-Spark serialization not working with inner classes

Elasticsearch / Spark序列化似乎不適合嵌套類型。

例如:

public class Foo implements Serializable {
   private List<Bar> bars = new ArrayList<Bar>();
   // getters and setters

   public static class Bar implements Serializable {
   }
}

List<Foo> foos = new ArrayList<Foo>();
foos.add( new Foo());
// Note: Foo object does not contain nested Bar instances

SparkConf sc = new SparkConf(); //
sc.setMaster("local");
sc.setAppName("spark.app.name");
sc.set("spark.serializer", KryoSerializer.class.getName()); 
JavaSparkContext jsc = new JavaSparkContext(sc);
JavaRDD javaRDD = jsc.parallelize(ImmutableList.copyOf(foos));
JavaEsSpark.saveToEs(javaRDD, INDEX_NAME+"/"+TYPE_NAME);  

上面的代碼可以工作, Foo類型的文檔將在Elasticsearch中編入索引。

Foo對象中的bars列表不為空時,會出現問題,例如:

Foo = new Foo();
Bar = new Foo.Bar();
foo.getBars().add(bar);

然后,在索引到Elasticsearch時,會拋出以下異常:

org.elasticsearch.hadoop.serialization.EsHadoopSerializationException: 
Cannot handle type [Bar] within type [class Foo], instance [Bar ...]] 
within instance [Foo@1cf628a] 
using writer [org.elasticsearch.spark.serialization.ScalaValueWriter@4e635d]
at org.elasticsearch.hadoop.serialization.builder.ContentBuilder.value(ContentBuilder.java:63)
at org.elasticsearch.hadoop.serialization.bulk.TemplatedBulk.doWriteObject(TemplatedBulk.java:71)
at org.elasticsearch.hadoop.serialization.bulk.TemplatedBulk.write(TemplatedBulk.java:58)
at org.elasticsearch.hadoop.rest.RestRepository.writeToIndex(RestRepository.java:148)
at org.elasticsearch.spark.rdd.EsRDDWriter.write(EsRDDWriter.scala:47)
at org.elasticsearch.spark.rdd.EsSpark$$anonfun$saveToEs$1.apply(EsSpark.scala:68)
at org.elasticsearch.spark.rdd.EsSpark$$anonfun$saveToEs$1.apply(EsSpark.scala:68)
at org.apache.spark.scheduler.ResultTask.runTask(ResultTask.scala:61)
at org.apache.spark.scheduler.Task.run(Task.scala:64)
at org.apache.spark.executor.Executor$TaskRunner.run(Executor.scala:203)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)

這些是相關的Maven依賴項

<dependency>
   <groupId>com.sksamuel.elastic4s</groupId>
   <artifactId>elastic4s_2.11</artifactId>
   <version>1.5.5</version>
</dependency>

<dependency>
   <groupId>org.apache.spark</groupId>
   <artifactId>spark-core_2.11</artifactId>
   <version>1.3.1</version>
</dependency>

<dependency>
   <groupId>org.elasticsearch</groupId>
   <artifactId>elasticsearch-hadoop-cascading</artifactId>
   <version>2.1.0.Beta4</version>
</dependency>

<dependency>
   <groupId>com.fasterxml.jackson.core</groupId>
   <artifactId>jackson-databind</artifactId>
   <version>2.1.3</version>
</dependency>

<dependency>
   <groupId>org.elasticsearch</groupId>
   <artifactId>elasticsearch-spark_2.10</artifactId>
   <version>2.1.0.Beta4</version>
</dependency>

<dependency>
   <groupId>org.scala-lang</groupId>
   <artifactId>scala-xml</artifactId>
   <version>2.11.0-M4</version>
</dependency>

在ElasticSearch和Spark中使用嵌套類型時索引的正確方法是什么?

謝謝

一個解決方案可能是使用例如Json4s從你想要保存的對象構建一個json。 在這種情況下,您的“JavaEsSpark”RDD將是字符串的RDD。 然后你只需要打電話

JavaEsSpark.saveJsonToEs...

代替

JavaEsSpark.saveToEs...

這種解決方法幫助我節省了無數個小時,試圖找到一種方法來序列化嵌套映射。

查看ScalaValueWriter和JdkValueWriter代碼,我們可以看到只有某些類型是直接支持的。 內部類很可能不是JavaBean或其他受支持的類型。

有一天,ScalaValueWriter和JdkValueWriter可能會支持用戶定義的類型(比如我們示例中的Bar ),而不僅僅是像String,int等Java類型。

與此同時,還有以下解決方法。 而不是讓Foo公開Bar對象列表,而是在內部將List轉換為Map<String, Object>並公開它。

像這樣的東西:

private List<Map<String, Object>> bars= new ArrayList<Map<String, Object>>();

public List<Map<String, Object>> getBars() {
   return bars;
}

public void setBars(List<Bar> bars) {
   for (Bar bar: bars){
      this.bars.add(bar.getAsMap());
   }
}

我建議使用com.google.gson.Gson;

String  foosJson = new Gson().toJson(foos );

然后,Map map = new HashMap <>(); ......

JavaRDD<Map<String,?>> javaRDD= sc.parallelize(ImmutableList.of(map));

JavaEsSpark.saveToEs ( javaRDD, INDEX_NAME+"/"+TYPE_NAME );

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM