我是ElasticSearch的新手。我有一个巨大的数据要使用Elasticsearch进行索引。
我使用Apache Spark使用Elasticsearch索引hive表中的数据。
作为此功能的一部分,我编写了简单的Spark脚本。
object PushToES {
def main(args: Array[String]) {
val Array(inputQuery, index, host) = args
val sparkConf = new SparkConf().setMaster("local[1]").setAppName("PushToES")
sparkConf.set("....",Host)
sparkConf.set("....","9200")
val sc = new SparkContext(sparkConf)
val ht = new org.apache.spark.sql.hive.HiveContext(sc)
val ps = hhiveSqlContext.sql(inputQuery)
ps.toJSON.saveJsonToEs(index)
}
}
之后,我正在使用spark-submit
生成jar并提交作业spark-submit --jars ~/*.jar --master local[*] --class com.PushToES *.jar "select * from gtest where day=20170711" gest3 localhost
然后我执行以下命令
curl -XGET 'localhost:9200/test/test_test/_count?pretty'
第一次正确显示
{
"count" : 10,
"_shards" : {
"total" : 5,
"successful" : 5,
"failed" : 0
}
}
如果我执行第二次相同的curl命令,它会给出像bleow
这样的结果{
"count" : 20,
"_shards" : {
"total" : 5,
"successful" : 5,
"failed" : 0
}
}
如果我执行第3次同样的命令我正在
{
"count" : 30,
"_shards" : {
"total" : 5,
"successful" : 5,
"failed" : 0
}
}
但我不是每次都理解为什么它会将计数值加到现有的索引值(即Count)
请让我知道如何解决这个问题,即。如果我执行任何数量的时间,我也必须得到相同的值(正确的计数值,即10)
I am expecting below result for this case because correct count value is 10
。(我在hive表上执行count查询以获取每次计数(*)为10)
{
"count" : 10,
"_shards" : {
"total" : 5,
"successful" : 5,
"failed" : 0
}
}
提前致谢。
答案 0 :(得分:1)
如果你想"替换"每次运行时的数据,而不是"追加"它,那么你必须在Spark Elasticsearch属性中配置这样的场景。
您需要做的第一件事就是在您的文档中有一个ID,并告诉我们你的id"列" (如果你来自数据框)或密钥(用json术语)。
此处记录了这些内容:https://www.elastic.co/guide/en/elasticsearch/hadoop/current/spark.html
对于需要指定文档的id(或其他元数据字段,如ttl或timestamp)的情况,可以通过设置适当的映射即es.mapping.id来实现。按照前面的示例,为了指示Elasticsearch使用字段id作为文档id,更新RDD配置(虽然不鼓励它的全局效果,但也可以在SparkConf上设置属性):
EsSpark.saveToEs(rdd, "spark/docs", Map("es.mapping.id" -> "id"))
第二个配置密钥可用于控制弹性搜索在写入数据时尝试执行的作业类型,但默认情况适用于您的用户案例:
es.write.operation(默认索引)
写操作elasticsearch-hadoop应该执行 - 可以是以下任何一个:
索引(默认) 添加新数据,同时替换现有数据(基于其id)(重新编制索引)。
创建 添加新数据 - 如果数据已存在(基于其id),则抛出异常。
更新 更新现有数据(基于其ID)。如果未找到任何数据,则抛出异常。
UPSERT 如果数据不存在,则称为合并或插入,如果数据存在则更新(基于其id)。