Elasticearch和Spark:更新现有实体

时间:2015-06-07 11:14:00

标签: elasticsearch apache-spark

使用Elasticsearch with Spark时,更新现有实体的正确方法是什么?

我想要以下内容:

  1. 将现有数据作为地图获取。
  2. 创建新地图,并使用更新后的字段填充该地图。
  3. 坚持新地图。
  4. 但是,有几个问题:

    1. 返回的字段列表不能包含_id,as it is not part of the source
    2. 如果为了测试,我在新值的映射中对现有的_id进行硬编码,则抛出以下异常:

      org.elasticsearch.hadoop.rest.EsHadoopInvalidRequest

    3. 如何检索_id,以及如何将其传递回Spark?

      我在下面添加了以下代码,以便更好地说明我的目标:

      JavaRDD<Map<String, Object>> esRDD = JavaEsSpark.esRDD(jsc, INDEX_NAME+"/"+TYPE_NAME, 
      "?source=,field1,field2).values();
      
      Iterator<Map<String, Object>> iter = esRDD.toLocalIterator();
      List<Map<String, Object>> listToPersist = new ArrayList<Map<String, Object>>();
      while(iter.hasNext()){
         Map<String, Object> map = iter.next();
         // Get existing values, and do transformation logic
      
         Map<String, Object> newMap = new HashMap<String, Object>();
         newMap.put("_id", ??????);
         newMap.put("field1", new_value);
         listToPersist.add(newMap);
      }
      JavaRDD javaRDD = jsc.parallelize(ImmutableList.copyOf(listToPersist));
      JavaEsSpark.saveToEs(javaRDD, INDEX_NAME+"/"+TYPE_NAME); 
      

      理想情况下,我希望更新现有地图,而不是创建新地图。

      在使用Spark时,是否有任何示例代码可以显示更新elasticsearch中现有实体的正确方法?

      谢谢

3 个答案:

答案 0 :(得分:0)

尝试将此upsert添加到Spark:

.config("es.write.operation", "upsert")

将允许您向现有文档添加新字段

答案 1 :(得分:0)

根据Elasticsearch Configuration,您可以通过将读取元数据选项设置为true来获得_id之类的文档元数据:

 .config("es.read.metadata", "true")

我认为您不能使用'_id'作为字段名称。

但是您可以使用其他名称创建新字段,例如:

 newMap.put("idfield", yourId);

然后将新字段的名称设置为“映射ID”选项的值,以通知Elastic该字段具有文档ID:

 .config("es.mapping.id", "idfield")

顺便说一句,不要忘记将写入操作设置为更新:

 .config("es.write.operation", "update")

答案 2 :(得分:0)

这就是我的操作方式(Scala / Spark 2.3 / Elastic-Hadoop v6.5)。

要读取(id或其他元数据):

Graphics

要更新ES中的特定列:

spark
    .read
    .format("org.elasticsearch.spark.sql")
    .option("es.read.metadata",true) // allow to read metadata
    .load("yourindex/yourtype")
    .select(col("_metadata._id").as("myId"),...)