org.springframework.boot
spring-boot-starter-parent
1.5.6.RELEASE
5.6.0
2.7
org.springframework.boot
spring-boot-starter-web
org.elasticsearch.client
transport
${elasticsearch.version}
org.apache.logging.log4j
log4j-core
${log4j.version}
这里SpringBoot使用的1.5.6.RELEASE版本,Elasticsearch的TransportClient是5.6.0版本,log4j是2.7版本
TransportClient是操作Elasticsearch集群的客户端API,它通过异步方式和ES集群进行交互
在application.yml中配置ES的服务地址【master的】和端口号【默认为9300】
创建Configuration配置类,使用@Configuration和@ConfigurationProperties(prefix = “配置的前缀”) 2个注解,声明属性,并提供对应的set方法
提供一个获取TransportClient的方法,并使用@Bean注解
用于创建TransportClient,使用预先安装好的插件(可选的)
通过addTransportAddress(TransportAddress transportAddress) {}方法,添加服务传输地址。需要传递一个InetSocketTransportAddress对象
public InetSocketTransportAddress(InetAddress address, int port) {}
传入ES的服务地址和端口即可
用于创建TransportClient时,所配置的参数。它有一个Map属性,用于存放配置
// we use a sorted map for consistent serialization when using getAsMap()
private final Map map = new TreeMap<>();
例如:当修改了默认的集群名称(elasticsearch)时,需要配置cluster.name ,并指定新的集群名称
【application.yml】
es:
host: ???.???.???.???
port: 9300
【配置类】
@Configuration
@ConfigurationProperties(prefix = "es")
public class MyConfig {
private String host;
private Integer port;
@Bean
public TransportClient getTransportClient() throws UnknownHostException {
TransportAddress transportAddress = new InetSocketTransportAddress(InetAddress.getByName(host), port);
Settings settings = Settings.builder().put("cluster.name", "集群名称").build();
TransportClient transportClient = new PreBuiltTransportClient(settings);
transportClient.addTransportAddress(transportAddress);
return transportClient;
}
public void setHost(String host) {
this.host = host;
}
public void setPort(Integer port) {
this.port = port;
}
}
用于创建请求JSON的建造者类
通过XContentFactory工厂类来创建
调用XContentFactory的jsonBuilder方法,其次调用startObject方法,表示要开始创建对象了,并通过field(String name, Object value) 方法给对象的属性赋值,最后调用endObject方法,表示对象创建完毕
通过调用TransportClient的prepareIndex(String index, String type) 方法,创建新的文档
传入索引和类型
其次再调用setSource方法,将生成的XContentBuilder传入
最后调用get 方法获取响应对象
Tips:可以通过IndexResponse的status方法,获取响应状态,通过RestStatus枚举类中的CREATED状态,来判断创建新文档是否成功
对于date类型的字段,如果使用java的Date转换后的字符串类型来存储,会减去8个小时,因为默认是按照UTC时区算的
所以推荐使用java.util.Date的getTime() 方法获取的毫秒数,这样就不会有时区的误差了
XContentBuilder sourceBuilder = XContentFactory.jsonBuilder()
.startObject()
.field("字段", "值")
.endObject();
IndexResponse indexResponse = transportClient.prepareIndex("索引", "类型")
.setSource(sourceBuilder).get();
if (RestStatus.CREATED.equals(indexResponse.status())) {
System.out.println("创建成功!");
} else {
System.out.println("创建失败!");
}
UpdateResponse
通过调用TransportClient的prepareUpdate(String index, String type, String id) 方法
传入索引、类型和要更新的文档的ID
再调用setDoc(XContentBuilder source) 方法
和保存时类似,传入XContentBuilder对象
最后调用get方法获取响应对象
同样地可以通过RestStatus枚举类的OK 来判断响应的状态是否更新成功
XContentBuilder source = XContentFactory.jsonBuilder()
.startObject()
.field("字段", "值")
.endObject();
UpdateResponse updateResponse = transportClient.prepareUpdate("索引", "类型", "要更新的文档的ID")
.setDoc(source)
.get();
if (RestStatus.OK.equals(updateResponse.status())) {
System.out.println("更新文档成功!");
} else {
System.out.println("更新文档失败!");
}
调用TransportClient的prepareDelete(String index, String type, String id) 方法
传入索引、类型、要删除的文档的ID
再调用get方法获取响应对象
可以通过RestStatus的OK 来判断是否删除成功
针对集群的管理员操作客户端
通过TransportClient的admin() 方法来获取
AdminClient的方法,可以操作多个索引
IndicesAdminClient的方法,可以删除多个索引
Tips:传入 “_all” 可以删除所有的索引
执行删除索引操作
AdapterActionFuture 的方法,
用于获取DeleteIndexResponse对象
用于判断删除索引是否成功。通过DeleteIndexResponse对象来调用
【删除一个文档】
DeleteResponse deleteResponse = transportClient.prepareDelete("索引", "类型", "要删除的文档的ID").get();
if (RestStatus.OK.equals(deleteResponse.status())) {
System.out.println("删除文档成功!");
} else {
System.out.println("删除文档失败!");
}
【删除一个索引】
DeleteIndexResponse deleteIndexResponse = transportClient.admin()
.indices()
.prepareDelete("要删除的索引")
.execute()
.actionGet();
if (deleteIndexResponse.isAcknowledged()) {
System.out.println("删除索引成功!");
} else {
System.out.println("删除索引失败!");
}
通过TransportClient调用GetRequestBuilder prepareGet(String index, String type, String id) 方法
传入索引、类型和要查询的文档的ID
再调用get方法,可以获取响应对象
获取响应的文档JSON内容,由JSON的key和value组成的Map。通过GetResponse调用
GetResponse getFields = transportClient.prepareGet("索引", "类型", "要查询的文档的ID").get();
Map source = getFields.getSource();
source.forEach((k, v) -> {System.out.println(k + " : " + v);});
用于创建过滤条件查询器
创建必须满足条件的查询器。需要传入查询创建器
创建可选满足条件的查询器。需要传入查询创建器
查询创建器,可以创建多种查询类型的查询器
⒈ MatchQueryBuilder matchQuery(String name, Object text);
匹配查询器。需要传入字段和要模糊匹配的内容
⒉ TermsQueryBuilder termsQuery(String name, Collection> values);
多个匹配查询器。需要传入字段和要精确匹配的内容的集合
⒊ RangeQueryBuilder rangeQuery(String name);
范围查询器。需要传入字段
RangeQueryBuilder from(Object from);
设置范围的起始条件
RangeQueryBuilder to(Object to);
设置范围的终止条件
RangeQueryBuilder gte(Object from);
设置范围要大于等于的条件
RangeQueryBuilder lt(Object to)
设置范围要小于的条件
过滤查询器。需要传入查询创建器
调用复合查询的方法,可以获取查询请求创建器。需要传入一个或多个索引
设置查询的类型
⒈ SearchType.DFS_QUERY_THEN_FETCH
当数据量不是很多时,可以选择此模式
它会匹配最精确的评分(分数高的)
⒉ SearchType.QUERY_THEN_FETCH
数据量多时,可以选择此查询类型
它会查询所有的分片,根据查询的条件返回对应的文档内容,此外还会匹配指定的返回文档的数量。所以在数据量很大时,它的效率是高的
设置查询的起始索引位置。默认为0,且不能小于0,否则报错
设置查询的文档的返回数量。默认为10
查询响应结果对象。通过SearchRequestBuilder(查询请求创建器)的get 方法来获取
查询到的结果集对象。通过SearchResponse来调用
获取查询到的文档的总的数量【该数量和最终返回的文档数量可能不一致。如果没有设置size,则默认返回10,否则就返回size个文档】
通过SearchHits来调用
获取查询到的结果集数组。通过SearchHits来调用【这才是最终返回的结果集】
public Map
获取每一个文档对应的Map类型的结果。通过SearchHit来调用
BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
boolQueryBuilder.must(QueryBuilders.matchQuery("字段", "要模糊匹配的内容"));
boolQueryBuilder.must(QueryBuilders.termQuery("字段", "要精确匹配的内容"));
boolQueryBuilder.should(QueryBuilders.termsQuery("字段", Arrays.asList("要精确匹配的内容1", "要精确匹配的内容2")));
RangeQueryBuilder rangeQueryBuilder = new RangeQueryBuilder("字段");
rangeQueryBuilder.from("范围起始内容");
rangeQueryBuilder.to("范围终止内容");
// rangeQueryBuilder.gt("范围要大于的内容");
// rangeQueryBuilder.lte("范围要小于等于的内容");
boolQueryBuilder.should(rangeQueryBuilder);
SearchRequestBuilder searchRequestBuilder = transportClient.prepareSearch("索引")
.setQuery(boolQueryBuilder)
.setSearchType(SearchType.DFS_QUERY_THEN_FETCH) // 文档数量不是很多
.setFrom(0) // 从0开始查询
.setSize(10); // 最终返回10个文档
System.out.println("查询JSON:\n" + searchRequestBuilder.toString());
SearchResponse searchResponse = searchRequestBuilder.get(); // 获取查询响应对象
SearchHits searchHits = searchResponse.getHits();
long totalHits = searchHits.getTotalHits();
System.out.println("匹配到的文档的总数:" + totalHits);
if (0 < totalHits) {
SearchHit[] hits = searchHits.getHits();
Map source;
for (SearchHit searchHit : hits) {
source = searchHit.getSource();
source.forEach((k, v) -> {System.out.println(k + " : " + v);});
}
}