使用JAVA来操作Elasticsearch,我的环境为
jdk1.8
ES5.6.8
transport 5.6.8
使用maven管理jar包,如果没有安装x-pack插件,只引入上第一个依赖就够
<dependency>
<groupId>org.elasticsearch.clientgroupId>
<artifactId>transportartifactId>
<version>5.6.8version>
dependency>
<dependency>
<groupId>org.elasticsearch.clientgroupId>
<artifactId>x-pack-transportartifactId>
<version>5.6.8version>
dependency>
使用封装的方式写一个工具类用于获取操作客户端,类似于jdbc中先写一个获取connection的方法。
/**
* 获取操作连接
* @return
*/
public static TransportClient getTransportClient() {
// 集群设置
Settings settings = Settings.builder()
.put("cluster.name", "elasticsearch")//集群名称
.build();
TransportClient client = new PreBuiltTransportClient(settings);
//添加集群地址和tcp服务端口 IP是由集群的各个node的ip组成的数组
try {
for (String ip : IP) {
client.addTransportAddresses(new InetSocketTransportAddress(InetAddress.getByName(ip), 9300));
}
} catch (UnknownHostException e) {
e.printStackTrace();
}
return client;
}
这里在贴一下安装了x-pack后使用的初始化方法
public static TransportClient getTransportClient() {
//安装x-pack后的初始化方法
Settings settings = Settings.builder()
.put("cluster.name", clusterName) //集群名
.put("client.transport.sniff", true)
.put("xpack.security.transport.ssl.enabled", false)
.put("xpack.security.user", "elastic:changme")//x-pack用户密码
.build();
//使用的实现类与前面不同
TransportClient client = new PreBuiltXPackTransportClient(settings);
// 一定要注意,9300为elasticsearch的tcp端口
try {
for (String ip : IP) {
client.addTransportAddresses(new InetSocketTransportAddress(InetAddress.getByName(ip), PORT));
}
} catch (UnknownHostException e) {
e.printStackTrace();
}
return client;
}
使用JAVA API创建一个带映射的索引,以通过它的field方法类设置
TransportClient transportClient = getTransportClient();
CreateIndexRequestBuilder createIndex=transportClient.admin().indices().prepareCreate(index);
XContentBuilder mapping = XContentFactory.jsonBuilder()
.startObject()
.startObject("properties") //设置之定义字段
.startObject("name").field("type","text").field("analyzed","standard").endObject() //设置分析器
.startObject("age").field("type","long").endObject()
.startObject("class_name").field("type","keyword").endObject()
.startObject("birth").field("type","date").field("format","yyyy-MM-dd").endObject()//设置Date的格式
.endObject()
.endObject();
createIndex.addMapping(type, mapping);
CreateIndexResponse res=createIndex.execute().actionGet();
构建一个request,它有很多类型,创建索引使用IndexRequestBuilder 。
可以不设置id,es可以自动生成_id.
source的类型有很多,可以使用XContentFactory创建XContentBuilder,也可以使用json格式的字符串 ,也可以使用Map来当数据源。
TransportClient client= ElasticSearchTestConfig.getTransportClient();
Map<String, Object> map = new HashMap<String, Object>();
map.put("name","张三");
map.put("age",22);
IndexRequestBuilder create = clien.prepareIndex("my","text")
.setSource(map);
IndexResponse response = create.execute().actionGet();
TransportClient client = ElasticSearchTestConfig.getTransportClient();
IndexRequestBuilder create = clien.prepareIndex("my","text")
.setSource(("{\"name\":\"张三\",\"age\":21 }",XContentType.JSON);
IndexResponse response = create.execute().actionGet();
使用BulkRequestBuilder 完成批量插入,虽然能完成批量操作,但一次也不要添加太多。因为request的大小有限制,具体的量与需要插入的数据大小有关。
BulkRequestBuilder bulkRequest = transportClient.prepareBulk();
for(Map source:sources){
//添加请求
bulkRequest.add(transportClient.prepareIndex(index,type)
.setSource(source));
}
BulkResponse bulkResponse = bulkRequest.execute().actionGet();
}
删除创建的是DeleteIndexRequestBuilder
//先判断下索引是否存在
IndicesExistsRequest inExistsRequest = new IndicesExistsRequest(index);
IndicesExistsResponse inExistsResponse = client.admin().indices()
.exists(inExistsRequest).actionGet();
//存在即进行删除操作
if(inExistsResponse.isExists()){
DeleteIndexRequestBuilder delete = client.admin().indices().prepareDelete(index);
DeleteIndexResponse dResponse = delete.execute().actionGet();
}
DeleteRequestBuilder delete = client.prepareDelete("my","text","1");
DeleteResponse response = delete.execute().actionGet();
其中Query是一种QueryBuilder
DeleteByQueryAction.INSTANCE.newRequestBuilder(client).filter(Query).execute();
一个搜索使用下面的方式构建使用。面对不同的需求使用不同的QueryBuilder。
TransportClient client = ElasticSearchTestConfig.getTransportClient();
//构建一个query 即查询条件
QueryBuilder match = QueryBuilders.matchQuery("field","text");
//根据查询条件构建一个查询问句
SearchRequestBuilder search = client.prepareSearch("index")
.setQuery(match)
.setTypes("typeName") //指定类型 可选
.setFrom(0).setSize(10) //分页 可选
.addSort("title", SortOrder.DESC);//排序 可选
//搜索返回搜索结果
SearchResponse response = search.get();
//命中的文档
SearchHits hits = response.getHits();
//命中总数
Long total = hits.getTotalHits()
//循环查看命中值
for(SearchHit hit:hits.getHits()){
//文档元数据
String index = hit.getIndex();
//文档的_source的值
Map<String, Object> sourceMap = hit.getSourceAsMap();
}
QueryBuilder matchAll = QueryBuilders.matchAllQuery();
QueryBuilder match = QueryBuilders.matchQuery("field","text");
QueryBuilder term = QueryBuilders.termQuery("field","text");
QueryBuilder terms = QueryBuilders.termsQuery("field","text","text2","text3");
QueryBuilder prefix= QueryBuilders.prefixQuery("field","text");
FuzzyQueryBuilder fuzzy= QueryBuilders.fuzzyQuery(field, value);
QueryBuilder wildcard= QueryBuilders.wildcardQuery(field,patten);
QueryBuilder queryString= QueryBuilders.queryStringQuery("queryString");
搜索需求:
重要性比较高:标题包含Elasticsearch或JAVA
内容同时包含Elasticsearch和JAVA
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
boolQuery.should(QueryBuilders.matchQuery("main_body","Elasticsearch JAVA")
.operator(Operator.AND).boost(1))
.should(QueryBuilders.matchQuery("title","Elasticsearch JAVA"))
.operator(Operator.OR).boost(10)
);
聚合相当于SQL中的group,使用不同的AggregationBuilder能完成不同的聚合操作,这里列举几种聚合。
语法如下:
TransportClient client = ElasticSearchTestConfig.getTransportClient();
//需要给聚合内容一个别名
AggregationBuilder aggregation = AggregationBuilders
.terms("alias").field("field");
QueryBuilder allQuery = QueryBuilders.matchAllQuery();
SearchResponse response = client.prepareSearch("index")
.setQuery(allQuery).addAggregation(aggregation).get();
//根据别名获取聚合对象,不同聚合会返回不同的聚合对象
Terms terms = response.getAggregations().get("alias");
for(Terms.Bucket entry:terms.getBuckets()){
//聚合的属性值
String value = entry.getKey().toString();
//聚合后的数量
long count = entry.getDocCount();
}
AggregationBuilder aggregation = AggregationBuilders
.terms("alias").field("field");
ValueCountBuilder vcb= AggregationBuilders.count("alias").field("field");
CardinalityBuilder aggregation = AggregationBuilders.cardinality("alias").field("field");
可选择不同的时间聚合方式
AggregationBuilder aggregation = AggregationBuilders
.dateHistogram(alias).field(field)
.format("yyyy-MM-dd")
.dateHistogramInterval(DateHistogramInterval.DAY);
搜索结果高亮显示,使用方法如下
TransportClient client = ElasticSearchTestConfig.getTransportClient();
QueryBuilder query = QueryBuilders.matchQuery("title","JAVA");
//创建高亮配置
HighlightBuilder hiBuilder=new HighlightBuilder();
//配置高亮作用字段
hiBuilder.field("title");
//可以设置返回高亮词周围多少字符,以及返回几个段
hiBuilder.field("main_body",100,1);
//在高亮词前添加标签
hiBuilder.preTags("");
//高亮词的后标签
hiBuilder.postTags("");
SearchResponse response = client.prepareSearch("index")
.setQuery(query).highlighter(hiBuilder).get();
//循环命中
for(SearchHit hit:response.getHits().getHits()){
//比如配置了两个字段都高亮,key是字段名,value就是加了高亮的值
Map highlightFieldMap = hit.getHighlightFields();
HighlightField highlightField = highlightFieldMap.get("title");
if(highlightField!=null){
//获取高亮的所有段
Text[] fragments = highlightField.getFragments();
for(Text text:fragments){
System.out.println("text的值是:"+text);
}
}
}
修改操作使用UpdateRequestBuilder构建一个修改请求,然后使用setDoc方法传入新的值即可,这里采用的不是覆盖而是更新存在值,新增不存在属性的操作
UpdateResponse response = client.prepareUpdate("my","test","1")
.setDoc(source).get();