如何使用Spark在ElasticSearch中使用脚本文档进行upsert或部分更新?

时间:2017-11-15 09:59:06

标签: python scala elasticsearch spark-streaming spark-structured-streaming

我在python中有一个伪代码,它从Kafka流中读取并在Elasticsearch中插入文档(如果文档已经存在,则递增计数器view

for message in consumer:

    msg = json.loads(message.value)
    print(msg)
    index = INDEX_NAME
    es_id = msg["id"]
    script = {"script":"ctx._source.view+=1","upsert" : msg}
    es.update(index=index, doc_type="test", id=es_id, body=script)

由于我想在分布式环境中使用它,我使用的是Spark Structured Streaming

df.writeStream \
.format("org.elasticsearch.spark.sql")\
.queryName("ESquery")\
.option("es.resource","credentials/url") \
.option("checkpointLocation", "checkpoint").start()

或scala中的SparkStreaming从KafkaStream读取:

// Initializing Spark Streaming Context and kafka stream
sparkConf.setMaster("local[2]")
val ssc = new StreamingContext(sparkConf, Seconds(10))
[...] 
val messages = KafkaUtils.createDirectStream[String, String](
      ssc,
      PreferConsistent,
      Subscribe[String, String](topicsSet, kafkaParams)
    )

[...]
val urls = messages.map(record => JsonParser.parse(record.value()).values.asInstanceOf[Map[String, Any]])
urls.saveToEs("credentials/credential")

.saveToEs(...)elastic-hadoop.jar记录here的API。遗憾的是this repo并没有得到很好的记录。所以我无法理解我可以把脚本命令放在哪里。

有没有人可以帮助我?提前谢谢

1 个答案:

答案 0 :(得分:3)

您应该可以通过设置写入模式"更新" (或upsert)并将脚本作为"脚本" (取决于ES版本)。

EsSpark.saveToEs(rdd, "spark/docs", Map("es.mapping.id" -> "id", "es.write.operation" -> "update","es.update.script.inline" -> "your script" , ))

可能你想使用" upsert"

同一个图书馆里有一些好的unit tests in cascading integration;这些设置应该对spark有好处,因为它们都使用相同的编写器。

我建议您阅读单元测试,为您的ES版本选择正确的设置。