3 Elasticsearch的Java编程接口
首先在maven工程pom.xml中添加依赖:
org.elasticsearch.client
transport
5.1.1
org.apache.logging.log4j
log4j-api
2.7
org.apache.logging.log4j
log4j-core
2.7
注意这一步要确保无误,否则会提示找不到PreBuiltTransportClient。
对应的在pom.xml中设置以下build参数:
src
maven-assembly-plugin
jar-with-dependencies
运行时指定第三方库的路径:
java -Djava.ext.dirs=./lib。
如果用maven来生成es_example-0.0.1-SNAPSHOT.jar,则用下列命令来执行jar包中的类:
java -cp es_example-0.0.1-SNAPSHOT.jar es_example.Main
es_example.Main是入口函数。
Maven生成命令:
mvn clean compile install assembly:assembly
3.1 创建客户端
客户端用TransportClient来连接。
创建时用以下代码:
// 设置集群名称
Settings mysettings = org.elasticsearch.common.settings.Settings
.builder().put("cluster.name", "elasticsearch").build();
// 创建client
try {
TransportClient client = new PreBuiltTransportClient(mysettings)
.addTransportAddress(new InetSocketTransportAddress(
InetAddress.getByName("127.0.0.1"), 9300));
return client;
} catch (UnknownHostException e) {
e.printStackTrace();
}
使用完之后要关闭客户端连接:
client.close();
3.1 新建索引
调用prepareCreate方法新建一个索引:
client.admin().indices().prepareCreate("example1").get();
3.2 查询单个文档
public static void query_es(TransportClient client) {
String index = "example1";
String type = "tp1";
String id = "1";
GetResponse getResponse = client.prepareGet() // 准备进行get操作,此时还有真正地执行get操作。(与直接get的区别)
.setIndex(index) // 要查询的
.setType(type).setId(id).get();
String data = getResponse.getSourceAsString();
System.out.println("data:" + data);
}
注意:索引名称支持多索引和通配符:
String index = "example1,example2";
String index = "example*";
3.3 查询文档列表
用SearchResponse来遍历多条数据。
public static void query_multi(TransportClient client) {
//设置查询条件
QueryBuilder queryBuilder =QueryBuilders.termQuery("name", "hello");
SearchResponse response = client.prepareSearch("example1")
.setQuery(queryBuilder).execute().actionGet();
for (SearchHit hit : response.getHits().getHits()) {
System.out.println("---->>hit.getId(): " + hit.getId());
String data = hit.getSourceAsString();
System.out.println("data:" + data);
}
}
3.4 多条件查询
使用boolQuery将多个查询条件绑定在一起。addSort还可以增加排序条件。
SearchRequestBuilder request = client.prepareSearch("bizCode").setTypes("bizCode");
BoolQueryBuilder query = QueryBuilders.boolQuery();
query.must(QueryBuilders.termQuery("bizCode",map.get("bizCode")));
query.must(QueryBuilders.termQuery("squareId",map.get("squareId")));
SearchResponse response =request.setQuery(query).addSort("createTime", SortOrder.DESC).execute().actionGet();
for (SearchHit hit : response.getHits().getHits()) {
System.out.println("---->>hit.getId(): " + hit.getId());
String data = hit.getSourceAsString();
System.out.println("data:" + data);
}
3.5 批量查询
es支持将多条查询语句包装在一个请求中,减少网络开销。
SearchRequestBuilder srb1 = client
.prepareSearch().setQuery(QueryBuilders.queryStringQuery("elasticsearch")).setSize(1);
SearchRequestBuilder srb2 = client
.prepareSearch().setQuery(QueryBuilders.matchQuery("name", "kimchy")).setSize(1);
MultiSearchResponse sr = client.prepareMultiSearch()
.add(srb1)
.add(srb2)
.get();
// You will get all individual responses from MultiSearchResponse#getResponses()
long nbHits = 0;
for (MultiSearchResponse.Item item : sr.getResponses()) {
SearchResponse response = item.getResponse();
nbHits += response.getHits().getTotalHits();
}
3.6 分页
用setFrom方法和setSize方法:
SearchResponse actionGet = elasticClient.prepareSearch("indexName")
.setTypes("typeName")
.setQuery(
QueryBuilders.boolQuery().must(QueryBuilders.termQuery("attr1", "value1"))
)
.setFrom(100)
.setSize(200)
.execute().actionGet();
3.7 聚合查询
3.7.1 平均值
// 设置查询条件
QueryBuilder queryBuilder = QueryBuilders.termQuery("name", "hou");
AvgAggregationBuilder aggBuilder = AggregationBuilders.avg("myage")
.field("age");
SearchResponse sr = client.prepareSearch().setQuery(queryBuilder)
.addAggregation(aggBuilder).execute().actionGet();
Map aggMap = sr.getAggregations().asMap();
for (String key:aggMap.keySet()){
Avg aggr=(Avg)aggMap.get(key);
System.out.println("key:"+key+",value:"+aggr.getValue());
}
3.7.2 最大最小值
// 设置查询条件
QueryBuilder queryBuilder = QueryBuilders.termQuery("name", "hou");
MaxAggregationBuilder aggBuilder = AggregationBuilders.max("myage")
.field("age");
SearchResponse sr = client.prepareSearch().setQuery(queryBuilder)
.addAggregation(aggBuilder).execute().actionGet();
Map aggMap = sr.getAggregations().asMap();
for (String key:aggMap.keySet()){
Max aggr=(Max)aggMap.get(key);
System.out.println("key:"+key+",value:"+aggr.getValue());
}
最小值则将max改成min就可以了,就不再举例子了。
3.8 新建文档
ES中一个索引就类似于数据库中一个表的概念。当然ES中的数据是非结构化的,意味着索引中的每条记录可以有不同的字段集合。
IndexResponse response = client.prepareIndex("twitter", "tweet", "1")
.setSource(jsonBuilder()
.startObject()
.field("user", "kimchy")
.field("postDate", new Date())
.field("message", "hello world")
.endObject()
).get();
3.9 删除文档
DeleteResponse response = client.prepareDelete("twitter", "tweet", "1").get();
prepareDelete一共三个参数,第一个是索引名称,这里是twitter;第二个是类型名称,这里是tweet;第三个是要删除的文档的主键,这里是1;删除方法返回类型是DeleteResponse。
3.10 操作对象
前面的例子基本都是字段级别的操作,如果一个文档的字段较少,这样操作没什么问题,如果我们用对象来编程,就需要在ES文档和Java对象间灵活的转变,这里举几个例子说明一下。
这里我们用alibaba的json包来处理。在pom.xml加入下面依赖:
com.alibaba
fastjson
1.2.29
/dependency>
首先定义一个对象来表示ES的文档,对象名MyObj,包含name和age两个字段,定义如下:
public class MyObj implements Serializable {
private static final long serialVersionUID = 640198637363779804L;
private String name;
private double age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getAge() {
eturn age;
}
public void setAge(double age) {
this.age = age;
}
}
然后在查询ES数据时将json格式转换成对象,整个代码如下:
public static void query_jsob_object(TransportClient client) {
// 设置查询条件
QueryBuilder queryBuilder = QueryBuilders.termQuery("name", "hello");
SearchResponse response = client.prepareSearch("example1")
.setQuery(queryBuilder).execute().actionGet();
for (SearchHit hit : response.getHits().getHits()) {
System.out.println("---->>hit.getId(): " + hit.getId());
MyObj obj = JSONObject.parseObject(hit.getSourceAsString(),
MyObj.class);
if (obj != null) {
System.out.println("json object name field:" + obj.getName());
}
}
}