众所周知,ElastcSearch支持通过http请求通过传输json的方式进行复杂查询,包括聚类、分类或是去重这些操作都可以通过ElasticSearch底层的Lucene来完成(关于Lucene的部分不在今天讨论范围,如果想进一步了解请移步Lucene源码)。言归正传,talk is cheap ,let's see the code:
一、工具类
首先写一个流文件转bute数组的工具类
/**
* inputstream转byte[]
*
* @param stream-输入字节流
* @return
*/
public static byte[] stream2byte(InputStream stream) {
if (stream == null)
return null;
ByteArrayOutputStream output = new ByteArrayOutputStream();
try {
byte[] buffer = new byte[4096];
int n = 0;
while (-1 != (n = stream.read(buffer))) {
output.write(buffer, 0, n);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
output.close();
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return output.toByteArray();
}
二、通过简单的json进行查询
/**
* 使用json查询数据
*
* @param requestUrl-请求的ES的URL
* @param esjson-查询的DSL
* @return
*/
public static String selectByJson(String requestUrl, String esjson) {
try {
HttpResponse response = HttpUtil.httpPost(requestUrl, esjson.getBytes());
return new String(FileUtil.stream2byte(response.getEntity().getContent()));
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
该方法可用于传递简单的json进行查询,比如查询数值,或者进行一些简单的大于小于的数值查询
三、通过.json模板文件进行复杂的查询
/**
* 使用模板查询数据
*
* @param requestUrl-请求的ES的URL
* @param template-查询的DSL模板
* @param paramMap-参数
* @return
*/
public static String selectByTemplate(String requestUrl, String template, Map
paramMap) {
try {
for (String paramKey : paramMap.keySet()) {
String json = gson.toJson(paramMap.get(paramKey));
template = template.replaceAll("@" + paramKey, json);
}
// System.out.println(template);
for (String replace : replaceArray) {
template = template.replaceAll(replace, "");
}
String result = selectByJson(requestUrl, template);
// System.out.println(result);
return result;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
该方法可以在.json模板里写入【@占位符】的形式来作为查询模板,占位符的内容作为paramMap的key,真正想要查询的内容作为对应的value,这样,就实现了一套模板查询进行不同信息的查询 ,如果条件写得好(也就是.json文件的结构),就可以实现各种
亿级数据的分类、聚类、去重等复杂查询的
秒级别返回,在后面的日记当中,我会开源一些对应的.json文件,实现这些海量数据的挖掘查询。