java操作elasticsearch詳細(xì)方法總結(jié)
一、前言
上一篇我們通過(guò)kibana的可視化界面,對(duì)es的索引以及文檔的常用操作做了畢竟詳細(xì)的總結(jié),本篇將介紹如何使用java完成對(duì)es的操作,這也是實(shí)際開發(fā)中將要涉及到的。
二、java操作es的常用模式
目前,開發(fā)中使用java操作es,不管是框架集成,還是純粹的使用es的api,主要通過(guò)下面兩種方式:
rest-api,主流的像 RestHighLevelClient ;
與springboot集成時(shí)的jpa操作,主要是 ElasticsearchRepository 相關(guān)的api;
上面兩種模式的api在開發(fā)中都可以方便的使用,相比之下,RestHighLevelClient相關(guān)的api靈活性更高,而ElasticsearchRepository 底層做了較多的封裝,學(xué)習(xí)和使用的成本更低,上手更快。
接下來(lái)將對(duì)上面的兩種操作模式做一個(gè)詳細(xì)的總結(jié),本篇所述的es基于7.6.2版本,配合的kibana也為7.6.2版本。
三、rest-api 操作
1、前置準(zhǔn)備
導(dǎo)入依賴
導(dǎo)入核心依賴,主要是es的rest依賴,其他的可以根據(jù)自己的需要導(dǎo)入;
<dependencies>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.11.2</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.11.2</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.8.2</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-jcl</artifactId>
<version>2.11.2</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>7.6.2</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.6.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.9</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>es連接測(cè)試
為了確保后續(xù)的所有實(shí)驗(yàn)?zāi)軌蛘_M(jìn)行,建議先通過(guò)下面的程序測(cè)試下是否能夠連接es服務(wù);
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import java.io.IOException;
public class EsClientTest {
public static void main(String[] args) throws IOException {
RestHighLevelClient esClient = new RestHighLevelClient(
RestClient.builder(new HttpHost("IP",9200,"http"))
);
System.out.println("success");
esClient.close();
}
}運(yùn)行上面的代碼,出現(xiàn)下面的效果說(shuō)明連接成功

2、索引相關(guān)操作api的使用
為了減少連接相關(guān)的編碼,我們將es的client提出到全局的靜態(tài)變量中,其他方法中就可以直接引用了
public static RestHighLevelClient esClient;
static {
esClient = new RestHighLevelClient(
RestClient.builder(new HttpHost("IP", 9200, "http"))
);
}2.1 創(chuàng)建索引
/**
* 創(chuàng)建索引
* @throws IOException
*/
public static void createIndex() throws IOException {
CreateIndexRequest createIndexRequest = new CreateIndexRequest("user");
CreateIndexResponse indexResponse = esClient.indices().create(createIndexRequest, RequestOptions.DEFAULT);
boolean acknowledged = indexResponse.isAcknowledged();
System.out.println("索引創(chuàng)建狀態(tài):" + acknowledged);
}main方法中調(diào)用方法即可
public static void main(String[] args) throws IOException {
System.out.println("connect success");
createIndex();
esClient.close();
}運(yùn)行main創(chuàng)建索引

通過(guò)kibana查詢確認(rèn)索引是否創(chuàng)建成功

2.2 獲取索引
/**
* 索引信息查詢
* @throws IOException
*/
public static void getIndex() throws IOException {
GetIndexRequest getIndexRequest = new GetIndexRequest("user");
GetIndexResponse getIndexResponse = esClient.indices().get(getIndexRequest, RequestOptions.DEFAULT);
System.out.println(getIndexResponse.getAliases());
System.out.println(getIndexResponse.getMappings());
System.out.println(getIndexResponse.getSettings());
}
2.3 刪除索引
/**
* 刪除索引
* @throws IOException
*/
public static void deleteIndex() throws IOException {
DeleteIndexRequest getIndexRequest = new DeleteIndexRequest("user");
AcknowledgedResponse delete = esClient.indices().delete(getIndexRequest, RequestOptions.DEFAULT);
System.out.println("索引刪除狀態(tài):" + delete.isAcknowledged());
}
3、文檔常用操作api的使用
在實(shí)際開發(fā)過(guò)程中,對(duì)于文檔的操作更為的頻繁,接下來(lái)演示與es文檔相關(guān)的操作api。
前置準(zhǔn)備
public static ObjectMapper objectMapper = new ObjectMapper();
public static RestHighLevelClient esClient;
static {
esClient = new RestHighLevelClient(
RestClient.builder(new HttpHost("IP", 9200, "http"))
);
}用于測(cè)試使用的對(duì)象
public class User {
private String name;
private String sex;
private Integer age;
private Integer salary;
public User() {
}
public User(String name, String sex, Integer age, Integer salary) {
this.name = name;
this.sex = sex;
this.age = age;
this.salary = salary;
}
public Integer getSalary() {
return salary;
}
public void setSalary(Integer salary) {
this.salary = salary;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}3.1 索引添加文檔
注意:實(shí)際開發(fā)中,user對(duì)象應(yīng)該作為參數(shù)傳入【可以基于此做進(jìn)一步的封裝】
/**
* 添加數(shù)據(jù)
* @throws Exception
*/
public static void add() throws Exception{
IndexRequest indexRequest = new IndexRequest();
indexRequest.index("user").id("1008");
User user = new User();
user.setName("孫二娘");
user.setAge(23);
user.setSex("女");
user.setSalary(7000);
String userData = objectMapper.writeValueAsString(user);
indexRequest.source(userData,XContentType.JSON);
//插入數(shù)據(jù)
IndexResponse response = esClient.index(indexRequest, RequestOptions.DEFAULT);
System.out.println(response.status());
System.out.println(response.getResult());
}在main方法調(diào)用執(zhí)行下該方法
public static void main(String[] args) throws Exception {
add();
esClient.close();
}
可以通過(guò)kibana查詢檢查下數(shù)據(jù)是否添加成功

3.2 修改文檔
/**
* 修改數(shù)據(jù)
* @throws Exception
*/
public static void update() throws Exception{
UpdateRequest request = new UpdateRequest();
request.index("user").id("1008");
request.doc(XContentType.JSON,"name","母夜叉");
//插入數(shù)據(jù)
UpdateResponse response = esClient.update(request, RequestOptions.DEFAULT);
System.out.println(response.getResult());
}
3.3 刪除文檔
/**
* 刪除
* @throws Exception
*/
public static void delete() throws Exception{
DeleteRequest request = new DeleteRequest();
request.index("user").id("1008");
//插入數(shù)據(jù)
DeleteResponse delete = esClient.delete(request, RequestOptions.DEFAULT);
System.out.println(delete.getResult());
}

3.4 批量添加文檔
有些情況下,單條插入效率太低,可以使用es的批量插入功能一次性添加多條數(shù)據(jù)
/**
* 批量添加
* @throws Exception
*/
public static void batchInsert() throws Exception{
BulkRequest bulkRequest = new BulkRequest();
User user1 = new User("關(guān)羽","男",33,5500);
String userData1 = objectMapper.writeValueAsString(user1);
IndexRequest indexRequest1 = new IndexRequest().index("user").id("1002").source(userData1, XContentType.JSON);
bulkRequest.add(indexRequest1);
User user2 = new User("黃忠","男",50,8000);
String userData2 = objectMapper.writeValueAsString(user2);
IndexRequest indexRequest2 = new IndexRequest().index("user").id("1003").source(userData2, XContentType.JSON);
bulkRequest.add(indexRequest2);
User user3 = new User("黃忠2","男",49,10000);
String userData3 = objectMapper.writeValueAsString(user3);
IndexRequest indexRequest3 = new IndexRequest().index("user").id("1004").source(userData3, XContentType.JSON);
bulkRequest.add(indexRequest3);
User user4 = new User("趙云","男",33,12000);
String userData4 = objectMapper.writeValueAsString(user4);
IndexRequest indexRequest4 = new IndexRequest().index("user").id("1005").source(userData4, XContentType.JSON);
bulkRequest.add(indexRequest4);
User user5 = new User("馬超","男",38,20000);
String userData5 = objectMapper.writeValueAsString(user5);
IndexRequest indexRequest5 = new IndexRequest().index("user").id("1006").source(userData5, XContentType.JSON);
bulkRequest.add(indexRequest5);
User user6 = new User("關(guān)羽","男",41,27000);
String userData6 = objectMapper.writeValueAsString(user6);
IndexRequest indexRequest6 = new IndexRequest().index("user").id("1007").source(userData6, XContentType.JSON);
bulkRequest.add(indexRequest6);
BulkResponse bulkResponse = esClient.bulk(bulkRequest, RequestOptions.DEFAULT);
System.out.println(bulkResponse.status());
System.out.println(bulkResponse.getItems());
}

3.5 批量刪除
可以通過(guò)批量操作一次性刪除多條數(shù)據(jù)
/**
* 批量刪除
* @throws Exception
*/
public static void batchDelete() throws Exception{
BulkRequest bulkRequest = new BulkRequest();
DeleteRequest indexRequest1 = new DeleteRequest().index("user").id("1002");
DeleteRequest indexRequest2 = new DeleteRequest().index("user").id("1003");
DeleteRequest indexRequest3 = new DeleteRequest().index("user").id("1004");
DeleteRequest indexRequest4 = new DeleteRequest().index("user").id("1005");
DeleteRequest indexRequest5 = new DeleteRequest().index("user").id("1006");
DeleteRequest indexRequest6 = new DeleteRequest().index("user").id("1007");
bulkRequest.add(indexRequest1);
bulkRequest.add(indexRequest2);
bulkRequest.add(indexRequest3);
bulkRequest.add(indexRequest4);
bulkRequest.add(indexRequest5);
bulkRequest.add(indexRequest6);
BulkResponse bulkResponse = esClient.bulk(bulkRequest, RequestOptions.DEFAULT);
System.out.println(bulkResponse.status());
System.out.println(bulkResponse.getItems());
}

4、文檔搜索相關(guān)api的使用
我們知道es最強(qiáng)大的功能就是文檔檢索了,接下來(lái)演示下與es文檔查詢相關(guān)的常用API的操作;
4.1 查詢某個(gè)索引下的所有數(shù)據(jù)
/**
* 查詢某個(gè)索引下的所有數(shù)據(jù)
* @throws Exception
*/
public static void searchIndexAll() throws Exception{
SearchRequest request = new SearchRequest();
request.indices("user");
// 索引中的全部數(shù)據(jù)查詢
SearchSourceBuilder query = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery());
request.source(query);
SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
SearchHits hits = response.getHits();
for (SearchHit searchHit : hits){
System.out.println(searchHit.getSourceAsString());
}
}執(zhí)行一下對(duì)該方法的調(diào)用

這個(gè)效果和在kibana中下面的操作效果是一樣的

4.2 批量查詢多條數(shù)據(jù)
針對(duì)那種需要一次性查出多條數(shù)據(jù)的場(chǎng)景可以考慮使用
MultiGetRequest multiGetRequest = new MultiGetRequest();
multiGetRequest.add("user", "1002");
multiGetRequest.add("user", "1003");
MultiGetResponse responses = esClient
.mget(multiGetRequest, RequestOptions.DEFAULT);
Iterator<MultiGetItemResponse> iterator = responses.iterator();
while (iterator.hasNext()){
MultiGetItemResponse next = iterator.next();
System.out.println(next.getResponse().getSourceAsString());
}
4.3 根據(jù)條件精準(zhǔn)查詢
根據(jù)性別查詢,有點(diǎn)類似于mysql 中的 where sex='女' 這樣的效果
TermQueryBuilder ageQueryBuilder = QueryBuilders.termQuery("sex", "女");
SearchSourceBuilder query = new SearchSourceBuilder().query(ageQueryBuilder);
request.source(query);
SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
System.out.println(response.getHits().getHits());
System.out.println(response.getHits().getTotalHits());
SearchHits hits = response.getHits();
for (SearchHit searchHit : hits){
System.out.println(searchHit.getSourceAsString());
}
4.4 分頁(yè)查詢
考察from + size的使用
SearchSourceBuilder sourceBuilder = new
SearchSourceBuilder().query(QueryBuilders.matchAllQuery());
sourceBuilder.from(0).size(3);
request.source(sourceBuilder);
SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
System.out.println(response.getHits().getHits());
System.out.println(response.getHits().getTotalHits());
SearchHits hits = response.getHits();
for (SearchHit searchHit : hits){
System.out.println(searchHit.getSourceAsString());
}
4.5 查詢結(jié)果按照某個(gè)字段進(jìn)行排序
將查詢結(jié)果按照age進(jìn)行排序
SearchSourceBuilder sourceBuilder = new
SearchSourceBuilder().query(QueryBuilders.matchAllQuery());
sourceBuilder.sort("age",SortOrder.ASC);
request.source(sourceBuilder);
SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
System.out.println(response.getHits().getHits());
System.out.println(response.getHits().getTotalHits());
SearchHits hits = response.getHits();
for (SearchHit searchHit : hits){
System.out.println(searchHit.getSourceAsString());
}
4.6 查詢結(jié)果過(guò)濾某些字段
類似于mysql中只查詢某個(gè)表的部分字段
SearchSourceBuilder sourceBuilder = new
SearchSourceBuilder().query(QueryBuilders.matchAllQuery());
request.source(sourceBuilder);
String[] includes = {"name","sex"};
String[] excludes = {"age"};
sourceBuilder.fetchSource(includes,excludes);
SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
System.out.println(response.getHits().getHits());
System.out.println(response.getHits().getTotalHits());
SearchHits hits = response.getHits();
for (SearchHit searchHit : hits){
System.out.println(searchHit.getSourceAsString());
}
4.7 多條件查詢
es可以像mysql那樣組合多個(gè)條件進(jìn)行查詢,考察對(duì)BoolQuery的使用,如下:查詢性別為難男,年齡在35到45之間的用戶;
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(QueryBuilders.matchQuery("sex","男"));
boolQueryBuilder.must(QueryBuilders.rangeQuery("age").lt(45).gt(35));
sourceBuilder.query(boolQueryBuilder);
request.source(sourceBuilder);
SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
System.out.println(response.getHits().getHits());
System.out.println(response.getHits().getTotalHits());
SearchHits hits = response.getHits();
for (SearchHit searchHit : hits){
System.out.println(searchHit.getSourceAsString());
}
4.8 范圍查詢
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
RangeQueryBuilder rangeQueryBuilder =
QueryBuilders.rangeQuery("age").gte(35).lte(45);
sourceBuilder.query(rangeQueryBuilder);
request.source(sourceBuilder);
SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
System.out.println(response.getHits().getHits());
System.out.println(response.getHits().getTotalHits());
SearchHits hits = response.getHits();
for (SearchHit searchHit : hits){
System.out.println(searchHit.getSourceAsString());
}
4.9 模糊查詢
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
FuzzyQueryBuilder fuzzyQueryBuilder =
QueryBuilders.fuzzyQuery("name", "黃忠")
.fuzziness(Fuzziness.ONE);
sourceBuilder.query(fuzzyQueryBuilder);
request.source(sourceBuilder);
SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
System.out.println(response.getHits().getHits());
System.out.println(response.getHits().getTotalHits());
SearchHits hits = response.getHits();
for (SearchHit searchHit : hits){
System.out.println(searchHit.getSourceAsString());
}
4.10 高亮查詢
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
TermQueryBuilder ageQueryBuilder = QueryBuilders.termQuery("age", 33);
HighlightBuilder highlightBuilder = new HighlightBuilder();
highlightBuilder.preTags("<font color='red'>");
highlightBuilder.postTags("</font>");
highlightBuilder.field("name");
sourceBuilder.highlighter(highlightBuilder);
sourceBuilder.query(ageQueryBuilder);
request.source(sourceBuilder);
SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
System.out.println(response.getHits().getHits());
System.out.println(response.getHits().getTotalHits());
SearchHits hits = response.getHits();
for (SearchHit searchHit : hits){
System.out.println(searchHit.getSourceAsString());
}4.11 多字段查詢multi_match
這個(gè)用法表示從多個(gè)字段中匹配某個(gè)關(guān)鍵字
SearchSourceBuilder builder = new SearchSourceBuilder();
MultiMatchQueryBuilder multiMatchQuery = QueryBuilders.multiMatchQuery("黃忠","name", "sex");
multiMatchQuery.operator(Operator.OR);
builder.query(multiMatchQuery);
request.source(builder);
SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
System.out.println(response.getHits().getHits());
System.out.println(response.getHits().getTotalHits());
SearchHits hits = response.getHits();
for (SearchHit searchHit : hits){
System.out.println(searchHit.getSourceAsString());
}
4.12 聚合查詢
SearchSourceBuilder builder = new SearchSourceBuilder();
AggregationBuilder aggregationBuilder = AggregationBuilders.max("maxAge").field("age");
builder.aggregation(aggregationBuilder);
request.source(builder);
SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
System.out.println(response.getHits().getHits());
System.out.println(response.getHits().getTotalHits());
SearchHits hits = response.getHits();
for (SearchHit searchHit : hits){
System.out.println(searchHit.getSourceAsString());
}4.13 分組查詢
SearchSourceBuilder builder = new SearchSourceBuilder();
AggregationBuilder aggregationBuilder = AggregationBuilders.terms("ageGroup").field("age");
builder.aggregation(aggregationBuilder);
request.source(builder);
SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
System.out.println(response.getHits().getHits());
System.out.println(response.getHits().getTotalHits());
SearchHits hits = response.getHits();
for (SearchHit searchHit : hits){
System.out.println(searchHit.getSourceAsString());
}四、與springboot 整合
es提供了與spring,springboot快速整合的第三方SDK,接下來(lái)以spring-data為例進(jìn)行說(shuō)明;
spring-boot-starter-data-elasticsearch 與spring其他相關(guān)的jpa方式使用類似,封裝了豐富的API接口,客戶只需要繼承其提供的接口,就能方便的使用內(nèi)置的API
前置準(zhǔn)備
本地創(chuàng)建一個(gè)maven工程
1、導(dǎo)入核心依賴
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.6.RELEASE</version>
<relativePath/>
</parent>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
</dependency>
</dependencies>2、核心配置文件
# es 服務(wù)地址 elasticsearch.host=IP # es 服務(wù)端口 elasticsearch.port=9200 # 配置日志級(jí)別,開啟 debug 日志 logging.level.com.congge=debug
整合過(guò)程
1、創(chuàng)建一個(gè)實(shí)體類
該實(shí)體類屬于連接es文檔與客戶端的一個(gè)中間轉(zhuǎn)換層,使用過(guò)jpa或者mybatis-plus的同學(xué)對(duì)這個(gè)應(yīng)該不陌生;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
@Document(indexName = "shopping", shards = 3, replicas = 1)
public class Product {
//必須有 id,這里的 id 是全局唯一的標(biāo)識(shí),等同于 es 中的"_id"
@Id
private Long id;//商品唯一標(biāo)識(shí)
/**
* type : 字段數(shù)據(jù)類型
* analyzer : 分詞器類型
* index : 是否索引(默認(rèn):true)
* Keyword : 短語(yǔ),不進(jìn)行分詞
*/
@Field(type = FieldType.Text, analyzer = "ik_max_word")
private String title;//商品名稱
@Field(type = FieldType.Keyword)
private String category;//分類名稱
@Field(type = FieldType.Double)
private Double price;//商品價(jià)格
@Field(type = FieldType.Keyword, index = false)
private String images;//圖片地址
}2、提供一個(gè)接口,繼承ElasticsearchRepository
import com.congge.entity.Product;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface ProductDao extends ElasticsearchRepository<Product, Long>{
}3、核心配置類
import lombok.Data;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
//import org.springframework.data.elasticsearch.config.AbstractElasticsearchConfiguration;
@ConfigurationProperties(prefix = "elasticsearch")
@Configuration
@Data
public class EsConfig extends com.congge.config.AbstractElasticsearchConfiguration {
private String host ;
private Integer port ;
//重寫父類方法
@Override
public RestHighLevelClient elasticsearchClient() {
RestClientBuilder builder = RestClient.builder(new HttpHost(host, port));
RestHighLevelClient restHighLevelClient = new
RestHighLevelClient(builder);
return restHighLevelClient;
}
}import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.context.annotation.Bean;
import org.springframework.data.elasticsearch.config.ElasticsearchConfigurationSupport;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
public abstract class AbstractElasticsearchConfiguration extends ElasticsearchConfigurationSupport {
//需重寫本方法
public abstract RestHighLevelClient elasticsearchClient();
@Bean(name = { "elasticsearchOperations", "elasticsearchTemplate" })
public ElasticsearchOperations elasticsearchOperations(ElasticsearchConverter elasticsearchConverter) {
return new ElasticsearchRestTemplate(elasticsearchClient(), elasticsearchConverter);
}
}模擬測(cè)試
接下來(lái)通過(guò)junit的方式進(jìn)行測(cè)試
1、索引相關(guān)的操作測(cè)試
import com.congge.entity.Product;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class EsIndexTest {
//注入 ElasticsearchRestTemplate
@Autowired
private ElasticsearchRestTemplate elasticsearchRestTemplate;
//創(chuàng)建索引并增加映射配置
@Test
public void createIndex(){
//創(chuàng)建索引,系統(tǒng)初始化會(huì)自動(dòng)創(chuàng)建索引
System.out.println("創(chuàng)建索引");
}
@Test
public void deleteIndex(){
//創(chuàng)建索引,系統(tǒng)初始化會(huì)自動(dòng)創(chuàng)建索引
boolean flg = elasticsearchRestTemplate.deleteIndex(Product.class);
System.out.println("刪除索引 = " + flg);
}
}基于spring-data的方式,在工程啟動(dòng)的時(shí)候,會(huì)自動(dòng)讀取實(shí)體類相關(guān)的注解,自動(dòng)完成索引的創(chuàng)建,運(yùn)行下創(chuàng)建索引的測(cè)試方法;

然后去到kibana上面確認(rèn)下是否創(chuàng)建成功;

2、文檔相關(guān)的操作測(cè)試
該測(cè)試類中列舉了常用的增刪改查操作
import com.congge.dao.ProductDao;
import com.congge.entity.Product;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.ArrayList;
import java.util.List;
@RunWith(SpringRunner.class)
@SpringBootTest
public class EsDocTest {
@Autowired
private ProductDao productDao;
/**
* 新增
*/
@Test
public void save() {
Product product = new Product();
product.setId(2L);
product.setTitle("ipad mini");
product.setCategory("ipad");
product.setPrice(1998.0);
product.setImages("http://ipad.jpg");
productDao.save(product);
}
//修改
@Test
public void update(){
Product product = new Product();
product.setId(2L);
product.setTitle("iphone");
product.setCategory("mobile");
product.setPrice(6999.0);
product.setImages("http://www.phone.jpg");
productDao.save(product);
}
//根據(jù) id 查詢
@Test
public void findById(){
Product product = productDao.findById(2L).get();
System.out.println(product);
}
//查詢所有
@Test
public void findAll(){
Iterable<Product> products = productDao.findAll();
for (Product product : products) {
System.out.println(product);
}
}
//刪除
@Test
public void delete(){
Product product = new Product();
product.setId(2L);
productDao.delete(product);
}
//批量新增
@Test
public void saveAll(){
List<Product> productList = new ArrayList<>();
for (int i = 0; i < 10; i++) {
Product product = new Product();
product.setId(Long.valueOf(i));
product.setTitle("iphone" + i);
product.setCategory("mobile");
product.setPrice(5999.0 + i);
product.setImages("http://www.phone.jpg");
productList.add(product);
}
productDao.saveAll(productList);
}
//分頁(yè)查詢
@Test
public void findByPageable(){
//設(shè)置排序(排序方式,正序還是倒序,排序的 id)
Sort sort = Sort.by(Sort.Direction.DESC,"id");
int currentPage=0;//當(dāng)前頁(yè),第一頁(yè)從 0 開始, 1 表示第二頁(yè)
int pageSize = 5;//每頁(yè)顯示多少條
//設(shè)置查詢分頁(yè)
PageRequest pageRequest = PageRequest.of(currentPage, pageSize,sort);
//分頁(yè)查詢
Page<Product> productPage = productDao.findAll(pageRequest);
for (Product Product : productPage.getContent()) {
System.out.println(Product);
}
}
/**
* term 查詢
* search(termQueryBuilder) 調(diào)用搜索方法,參數(shù)查詢構(gòu)建器對(duì)象
*/
@Test
public void termQuery(){
TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("title", "iphone");
Iterable<Product> products = productDao.search(termQueryBuilder);
for (Product product : products) {
System.out.println(product);
}
}
/**
* term 查詢加分頁(yè)
*/
@Test
public void termQueryByPage(){
int currentPage= 0 ;
int pageSize = 5;
//設(shè)置查詢分頁(yè)
PageRequest pageRequest = PageRequest.of(currentPage, pageSize);
TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("title", "phone");
Iterable<Product> products =
productDao.search(termQueryBuilder,pageRequest);
for (Product product : products) {
System.out.println(product);
}
}
}測(cè)試其中批量新增的方法

更多豐富的API接口的使用有興趣的同學(xué)可以基于此繼續(xù)深入的研究學(xué)習(xí)。
總結(jié)
到此這篇關(guān)于java操作elasticsearch詳細(xì)方法的文章就介紹到這了,更多相關(guān)java操作elasticsearch內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Java使用ES?Client?調(diào)用滾動(dòng)查詢及Elasticsearch滾動(dòng)查詢Scrolling機(jī)制
- Java ES(Elasticsearch) 中的and 和 or 查詢
- Java中Elasticsearch 實(shí)現(xiàn)分頁(yè)方式(三種方式)
- elasticsearch構(gòu)造Client實(shí)現(xiàn)java客戶端調(diào)用接口示例分析
- 關(guān)于Java中配置ElasticSearch集群環(huán)境賬號(hào)密碼的問(wèn)題
- java 通過(guò)聚合查詢實(shí)現(xiàn)elasticsearch的group by后的數(shù)量
- Java在ElasticSearch中使用LocalDatetime類型
相關(guān)文章
基于HTTP協(xié)議實(shí)現(xiàn)簡(jiǎn)單RPC框架的方法詳解
RPC全名(Remote?Procedure?Call),翻譯過(guò)來(lái)就是遠(yuǎn)程過(guò)程調(diào)用,本文將為大家介紹如何基于HTTP協(xié)議實(shí)現(xiàn)簡(jiǎn)單RPC框架,感興趣的小伙伴可以了解一下2023-06-06
Java導(dǎo)出Excel統(tǒng)計(jì)報(bào)表合并單元格的方法詳解
我們?cè)谌粘>幊踢^(guò)程中,總是會(huì)碰見導(dǎo)出相關(guān)表格信息的需求,所以就讓我們一起來(lái)學(xué)習(xí)一下,這篇文章主要給大家介紹了關(guān)于Java導(dǎo)出Excel統(tǒng)計(jì)報(bào)表合并單元格的相關(guān)資料,需要的朋友可以參考下2021-10-10
java使用wait()和notify()線程間通訊的實(shí)現(xiàn)
Java 線程通信是將多個(gè)獨(dú)立的線程個(gè)體進(jìn)行關(guān)聯(lián)處理,使得線程與線程之間能進(jìn)行相互通信,本文就介紹了java使用wait()和notify()線程間通訊的實(shí)現(xiàn),感興趣的可以了解一下2023-09-09
mybatis?查詢返回Map<String,Object>類型
本文主要介紹了mybatis?查詢返回Map<String,Object>類型,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-03-03
Java面試synchronized偏向鎖后hashcode存址
這篇文章主要為大家介紹了Java面試中synchronized偏向鎖后hashcode存址詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05
Java ArrayList與Vector和LinkedList的使用及源碼分析
ArrayList、Vector、LinkedList類均在java.util包中,均為可伸縮數(shù)組,即可以動(dòng)態(tài)改變長(zhǎng)度的數(shù)組。ArrayList 和 Vector都是基于存儲(chǔ)元素的Object[] array來(lái)實(shí)現(xiàn)的,它們會(huì)在內(nèi)存中開辟一塊連續(xù)的內(nèi)存來(lái)存儲(chǔ)2022-11-11
基于Redis分布式鎖Redisson及SpringBoot集成Redisson
這篇文章主要介紹了基于Redis分布式鎖Redisson及SpringBoot集成Redisson,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小小伙伴可以參考一下2022-09-09
Java實(shí)現(xiàn)定時(shí)任務(wù)的方法總結(jié)
這篇文章主要為大家詳細(xì)介紹了Java中實(shí)現(xiàn)定時(shí)任務(wù)的常用7中方法,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,需要的小伙伴可以參考一下2023-06-06

