我们将一些json数据存储到HDFS中,我们尝试使用elasticsearch-hadoop map reduce将数据摄取到Elasticsearch中。
我们使用的代码非常简单(下面)
public class TestOneFileJob extends Configured implements Tool {
public static class Tokenizer extends MapReduceBase
implements Mapper<LongWritable, Text, LongWritable, Text> {
@Override
public void map(LongWritable arg0, Text value, OutputCollector<LongWritable, Text> output,
Reporter reporter) throws IOException {
output.collect(arg0, value);
}
}
@Override
public int run(String[] args) throws Exception {
JobConf job = new JobConf(getConf(), TestOneFileJob.class);
job.setJobName("demo.mapreduce");
job.setInputFormat(TextInputFormat.class);
job.setOutputFormat(EsOutputFormat.class);
job.setMapperClass(Tokenizer.class);
job.setSpeculativeExecution(false);
FileInputFormat.setInputPaths(job, new Path(args[1]));
job.set("es.resource.write", "{index_name}/live_tweets");
job.set("es.nodes", "els-test.css.org");
job.set("es.input.json", "yes");
job.setMapOutputValueClass(Text.class);
JobClient.runJob(job);
return 0;
}
public static void main(String[] args) throws Exception {
System.exit(ToolRunner.run(new TestOneFileJob(), args));
}
}
此代码工作正常,但我们有两个问题。
第一个问题是es.resource.write
属性的值。目前,它由json的属性index_name
提供。
如果json包含类型为array的属性,如
{
"tags" : [{"tag" : "tag1"}, {"tag" : "tag2"}]
}
我们如何配置es.resource.write
以获取第一个tag
值?
我们尝试使用{tags.tag}
和{tags[0].tag}
,但要么不起作用。
另一个问题是,如何在tags属性的两个值中将作业索引作为json文档?
答案 0 :(得分:0)
我们通过以下方式解决了这两个问题
1-在run方法中,我们将es.resource.write
的值设为如下
job.set("es.resource.write", "{tag}/live_tweets");
2-在map函数中,我们使用gson库将json转换为对象
Object currentValue = gson.fromJson(jsonString, Object.class);
POJO
3-从Object我们可以提取我们想要的标签,并将其值作为新属性添加到json。
前面的步骤解决了第一个问题。关于第二个问题(如果我们希望根据标签的数量将相同的json存储到多个索引中),我们只需循环遍历json中的标签并更改我们添加的标签属性,然后再将json传递给收集器。以下是此步骤所需的代码。
@Override
public void map(LongWritable arg0, Text value, OutputCollector<LongWritable, Text> output, Reporter reporter)
throws IOException {
List<String> tags = getTags(value.toString());
for (String tag : tags) {
String newJson = value.toString().replaceFirst("\\{", "{\"tag\":\""+tag+"\",");
output.collect(arg0, new Text(newJson));
}
}