简介
本人文笔确实槽糕,拍说不清,反而让人感觉不明白,官网的介绍感觉挺直接的 Search & Analyze Data in Real Time ,详细直接复制网址查看https://www.elastic.co/products/elasticsearch。
准备工作
首先引入jar包依赖,由于es在索引是是接收json数据,所以把fastjson一并引入
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.5</version>
</dependency>
测试数据:假如我要导入一个订单表的数据到es中,字段如下
orderId 订单号
cusName 客户姓名
cusPhone 客户电话
amount 订单金额
orderTime 下单时间
新建一个OrderVo 对象,字段包含以上。
主要类
如果我们把es当做一个数据库来看的话,那我们就可以这样理解,如果我们要操作es,首先得连接到es,我们可以增加数据,修改数据,删除数据,当然还有最重要的搜索功能(即相当于数据库的查询)
1 TransportClient 客户端类,可以理解为e客户端
2 Setting 设置连接配置信息的,可以理解为properties
3 QueryBuilder 查询组装类
4 QueryBuilder 查询组装类
5 IndexRequestBuilder 索引结果返回类
6 BulkRequestBuilder 批量索引返回类
7 SearchResponse 搜索结果返回类
创建TransportClient
建议将 TransportClient 作为一个内部静态单列,因为创建client是很费资源的。端口默认是9300
private TransportClient getClient(){
if(null != this.client){
return client;
}
Settings settings = Settings.settingsBuilder()
.put("client.transport.sniff", true)
.build();
try {
client = TransportClient.builder().settings(settings).build()
.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("192.168.152.128"), 9300));
} catch (UnknownHostException e) {
e.printStackTrace();
}
return client;
}
索引数据
索引数据,其实也是新增或者修改数据,es会根据id来判断是否存在数据,存在就修改,不存在直接信息,id是可以自己设置,也可以用默认的,通常我们的id都有数据库的主键,因此在写入数据时是需要指定id的,这里的indexName 和 type 我都设置为静态变量 这里只是展示api,具体是什么就没关系了
private void importOne(BillVo billMain){
String id = billVo.getOrderId()+"";
IndexRequestBuilder requestBuilder = getClient().prepareIndex(indexName, type).setRefresh(true);
JSONObject obj = (JSONObject) JSON.toJSON(billMain);
requestBuilder.setId(id).setSource(obj).execute().actionGet();
}
当初次写入数据时es会根据json内容自动匹配字段类型,es字段类型请参考 http://www.cnblogs.com/xing901022/p/5471419.html
批量索引
private void batchImport(List<IndexRequestBuilder> list){
BulkRequestBuilder bulkRequest = getClient().prepareBulk().setRefresh(true);
for (IndexRequestBuilder indexRequestBuilder : list){
bulkRequest.add(indexRequestBuilder);
}
BulkResponse bulkResponse = bulkRequest.execute().actionGet();
if(bulkResponse.hasFailures()){
System.out.println("导入有错!");
}
}
查询数据
public Map<String,Object> queryListFromEs(BillVo billVo,int start,int pageSize){
Map<String,Object> result = new HashMap();
BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
if(null != billVo.getOrderId()){
queryBuilder.must(QueryBuilders.termQuery("orderId",billVo.getOrderId()));
}
SearchResponse searchResponse = getClient().prepareSearch(indexName).setTypes(type)
.setQuery(queryBuilder)
.setFrom(start).setSize(pageSize)
.execute()
.actionGet();
SearchHits hits = searchResponse.getHits();
System.out.println("查询到记录数=" + hits.getTotalHits());
SearchHit []hit = hits.getHits();
List<(BillVo > bmList = new ArrayList<>();
for(SearchHit h : hit){
JSONObject json = (JSONObject) JSONObject.toJSON(h.getSource());
BillVo bm = json2BillVo(json);
bmList.add(bm);
}
result.put("bmList",bmList);
result.put("total",hits.getTotalHits());
return result;
}
scroll方式分页查询
第一次传人scrollId为空,当获取到scrollId后,再去根据scrollId查询第一页数据,建议每次都把scrollId返回,下次请求把返回的scorllId也传人,这样就可以直接根据scrollId取值了。
public Map<String,Object> scrollQuery(BillVo billVo,String startDate,String endDate,String scrollId,int start,int pageSize){
BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
if (null != billVo.getOrderId()){
queryBuilder.must(QueryBuilders.termQuery("orderId",billVo.getOrderId));
}
Map<String,Object> result = new HashMap<>();
if (StringUtils.isEmpty(scrollId)){
SearchResponse scrollResp = getClient().prepareSearch(indexName).setTypes(type)
.setScroll(new TimeValue(30000)) // 1 mn
.setQuery(queryBuilder)
.setSize(10)
.execute()
.actionGet();
scrollId = scrollResp.getScrollId();
}
SearchResponse scrollResp = getClient().prepareSearchScroll(scrollId)
.setScroll(new TimeValue(30000)) // 1 mn
.execute().actionGet();
SearchHits hits = scrollResp.getHits();
SearchHit []hit = hits.getHits();
List<BillVo> bmList = new ArrayList<>();
for(SearchHit h : hit){
JSONObject json = (JSONObject) JSONObject.toJSON(h.getSource());
BillVo bm = json2BillVo(json);
bmList.add(bm);
}
result.put("bmList",bmList);
result.put("total",hits.getTotalHits());
if(bmList.size() >= pageSize){
result.put("scrollId",scrollResp.getScrollId());
System.out.println(scrollResp.getScrollId());
}
return result;
}
分组查询
private void aggQuery(BillVo billVo){
TermsBuilder gradeTermsBuilder = AggregationBuilders.terms("partnerAgg").field("cusName");
gradeTermsBuilder.size(0);//不指定size默认只有10条,0表示全部
SearchResponse searchResponse = getClient().prepareSearch(indexName).setTypes(type)
.addAggregation(gradeTermsBuilder)
.execute()
.actionGet();
System.out.println("group :"+gradeTermsBuilder);
Map<String, Aggregation> aggMap = searchResponse.getAggregations().asMap();
LongTerms terms = (LongTerms) aggMap.get("partnerAgg");
Iterator<Terms.Bucket> iterator = terms.getBuckets().iterator();
long total = 0;
while(iterator.hasNext()){
Terms.Bucket bucket = iterator.next();
total = total + bucket.getDocCount();
System.out.println("cusName="+bucket.getKey()+",有"+bucket.getDocCount()+"条");
}
System.out.println("分组合计"+total);
}
求和统计
private void metricQuery(){
MetricsAggregationBuilder aggregation =AggregationBuilders.sum("sumBar").field("amount");
SearchResponse searchResponse = getClient().prepareSearch(indexName).setTypes(type)
.addAggregation(aggregation)
.execute()
.actionGet();
InternalSum amountSum = searchResponse.getAggregations().get("sumBar");
System.out.println("bargainAmount total = "+amountSum.getValue());
}