1 SpringBoot整合ElasticSearch
1.1 pom依賴和版本關(guān)系
1.1.1 pom.xml
導(dǎo)入elasticsearch
依賴,在pom.xml
里加入如下依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
注意
:檢查依賴版本是否與前所用的版本是否一致,如果不一致,會(huì)連接失敗
1.1.2 版本關(guān)系
SpringBoot
版本問(wèn)題尺碰,SpringBoot
的版本對(duì)應(yīng)不上ES的版本
Spring Data Release Train | Spring Data Elasticsearch | Elasticsearch | Spring Framework | Spring Boot |
---|---|---|---|---|
2021.2 (Raj) | 4.4.x | 7.17.9 | 5.3.x | 2.7.x |
2021.1 (Q) | 4.3.x | 7.15.2 | 5.3.x | 2.6.x |
2021.0 (Pascal) | 4.2.x[1] | 7.12.0 | 5.3.x | 2.5.x |
2020.0 (Ockham)[1] | 4.1.x[1] | 7.9.3 | 5.3.2 | 2.4.x |
Neumann[1] | 4.0.x[1] | 7.6.2 | 5.2.12 | 2.3.x |
Moore[1] | 3.2.x[1] | 6.8.12 | 5.2.12 | 2.2.x |
Lovelace[1] | 3.1.x[1] | 6.2.2 | 5.1.19 | 2.1.x |
Kay[1] | 3.0.x[1] | 5.5.0 | 5.0.13 | 2.0.x |
Ingalls[1] | 2.1.x[1] | 2.4.0 | 4.3.25 | 1.5.x |
由于以上ElasticSearch
版本之間的差距導(dǎo)致對(duì)應(yīng)Spring Data ElasticSearch
包的差距糙麦;所以在不降低 Spring Boot
版本的情況需兼容低版本的 ElasticSearch
的客戶端。
解決方法:
- 方案一
由于不兼容厨疙,即放棄Spring Data ElasticSearch
框架包,使用最直接的Java ElasticSearch Client
連接即可疑务,將Client
注入到Spring
容器中沾凄,使用High/Low Level Client API
連接也是可以的(HighLevel
是在LowLevel Client
的基礎(chǔ)上封裝而成的)
點(diǎn)擊查看JavaAPI操作ES - 方案二
由于SpringBoot 2.3.x
以上版本只支持ES7
服務(wù)梗醇,所以對(duì)于一些本身為SpringBoot
高版本的項(xiàng)目而言單純的引入spring-boot-starter-data-elasticsearch
模塊包是存在兼容性問(wèn)題的,所以需要將Spring Data ElasticSearch
單獨(dú)引入撒蟀,由于ES6
對(duì)應(yīng)的Spring Data ElasticSearch 為3.2.x
版本
1.2 創(chuàng)建客戶端
1.2.1 高級(jí)客戶端
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ElasticSearchClientConfig {
@Bean
public RestHighLevelClient restHighLevelClient(){
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(
new HttpHost("服務(wù)器IP", 9200, "http")));
return client;
}
}
1.2.2 ES 8.0后客戶端
@ConfigurationProperties(prefix = "elasticsearch")
@Configuration
@Data
public class ElasticsearchConfig {
//多個(gè)IP逗號(hào)隔開
private String hosts;
private String username;
private String password;
/**
* 同步方式
*/
@Bean
public ElasticsearchClient elasticsearchClient() {
HttpHost[] httpHosts = toHttpHost();
// 用戶認(rèn)證對(duì)象
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
// 設(shè)置賬號(hào)密碼
credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username, password));
// Create the RestClient
RestClient restClient = RestClient.builder(httpHosts).setHttpClientConfigCallback(hp -> {
//es 毙鸾鳎活,可以確保每次連接不是重新建立tcp 連接
hp.setKeepAliveStrategy((response, context) -> Duration.ofMinutes(5).toMillis());
hp.disableAuthCaching();
hp.setDefaultCredentialsProvider(credentialsProvider);
return hp;
}).build();
// Create the transport with a Jackson mapper
RestClientTransport transport = new RestClientTransport(restClient, new JacksonJsonpMapper());
// create the API client
return new ElasticsearchClient(transport);
}
/**
* 異步方式
*/
public ElasticsearchAsyncClient elasticsearchAsyncClient() {
HttpHost[] httpHosts = toHttpHost();
RestClient restClient = RestClient.builder(httpHosts).build();
RestClientTransport transport = new RestClientTransport(restClient, new JacksonJsonpMapper());
return new ElasticsearchAsyncClient(transport);
}
/**
* 解析配置的字符串hosts牙肝,轉(zhuǎn)為HttpHost對(duì)象數(shù)組
*/
private HttpHost[] toHttpHost() {
if (!StringUtils.hasLength(hosts)) {
throw new RuntimeException("invalid elasticsearch configuration. elasticsearch.hosts is null");
}
// 多個(gè)IP逗號(hào)隔開
String[] hostArray = hosts.split(",");
HttpHost[] httpHosts = new HttpHost[hostArray.length];
HttpHost httpHost;
for (int i = 0; i < hostArray.length; i++) {
String[] strings = hostArray[i].split(":");
httpHost = new HttpHost(strings[0], Integer.parseInt(strings[1]), "http");
httpHosts[i] = httpHost;
}
return httpHosts;
}
}
使用時(shí)注入 ElasticsearchClient
即可
@Autowired
private ElasticsearchClient elasticsearchClient;
注意
:ES8.0
后推薦用 ElasticsearchClient
唉俗,而不是 RestHighLevelClient
1.3 基本用法
1.3.1 創(chuàng)建、判斷存在配椭、刪除索引
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.io.IOException;
@SpringBootTest
public class ElasticsearchApplicationTests {
@Autowired
private RestHighLevelClient restHighLevelClient;
@Test
void testCreateIndex() throws IOException {
//1.創(chuàng)建索引請(qǐng)求
CreateIndexRequest request = new CreateIndexRequest("ljx666");
//2.客戶端執(zhí)行請(qǐng)求IndicesClient虫溜,執(zhí)行create方法創(chuàng)建索引,請(qǐng)求后獲得響應(yīng)
CreateIndexResponse response=
restHighLevelClient.indices().create(request, RequestOptions.DEFAULT);
System.out.println(response);
}
@Test
void testExistIndex() throws IOException {
//1.查詢索引請(qǐng)求
GetIndexRequest request=new GetIndexRequest("ljx666");
//2.執(zhí)行exists方法判斷是否存在
boolean exists=restHighLevelClient.indices().exists(request,RequestOptions.DEFAULT);
System.out.println(exists);
}
@Test
void testDeleteIndex() throws IOException {
//1.刪除索引請(qǐng)求
DeleteIndexRequest request=new DeleteIndexRequest("ljx666");
//執(zhí)行delete方法刪除指定索引
AcknowledgedResponse delete = restHighLevelClient.indices().delete(request, RequestOptions.DEFAULT);
System.out.println(delete.isAcknowledged());
}
}
1.3.2 對(duì)文檔的CRUD
創(chuàng)建文檔
注意
:如果添加時(shí)不指定文檔ID股缸,他就會(huì)隨機(jī)生成一個(gè)ID衡楞,ID唯一。
創(chuàng)建文檔時(shí)若該ID已存在敦姻,發(fā)送創(chuàng)建文檔請(qǐng)求后會(huì)更新文檔中的數(shù)據(jù)瘾境。
@Test
void testAddUser() throws IOException {
//1.創(chuàng)建對(duì)象
User user=new User("Go",21,new String[]{"內(nèi)卷","吃飯"});
//2.創(chuàng)建請(qǐng)求
IndexRequest request=new IndexRequest("ljx666");
//3.設(shè)置規(guī)則 PUT /ljx666/_doc/1
//設(shè)置文檔id=6,設(shè)置超時(shí)=1s等镰惦,不設(shè)置會(huì)使用默認(rèn)的
//同時(shí)支持鏈?zhǔn)骄幊倘?request.id("6").timeout("1s");
request.id("6");
request.timeout("1s");
//4.將數(shù)據(jù)放入請(qǐng)求迷守,要將對(duì)象轉(zhuǎn)化為json格式
//XContentType.JSON,告訴它傳的數(shù)據(jù)是JSON類型
request.source(JSONValue.toJSONString(user), XContentType.JSON);
//5.客戶端發(fā)送請(qǐng)求旺入,獲取響應(yīng)結(jié)果
IndexResponse indexResponse=restHighLevelClient.index(request,RequestOptions.DEFAULT);
System.out.println(indexResponse.toString());
System.out.println(indexResponse.status());
}
獲取文檔中的數(shù)據(jù):
@Test
void testGetUser() throws IOException {
//1.創(chuàng)建請(qǐng)求,指定索引兑凿、文檔id
GetRequest request=new GetRequest("ljx666","1");
GetResponse getResponse=restHighLevelClient.get(request,RequestOptions.DEFAULT);
System.out.println(getResponse);//獲取響應(yīng)結(jié)果
//getResponse.getSource() 返回的是Map集合
System.out.println(getResponse.getSourceAsString());//獲取響應(yīng)結(jié)果source中內(nèi)容,轉(zhuǎn)化為字符串
}
更新文檔數(shù)據(jù):
注意
:需要將User對(duì)象中的屬性全部指定值茵瘾,不然會(huì)被設(shè)置為空礼华,如User只設(shè)置了名稱,那么只有名稱會(huì)被修改成功拗秘,其他會(huì)被修改為null圣絮。
@Test
void testUpdateUser() throws IOException {
//1.創(chuàng)建請(qǐng)求,指定索引、文檔id
UpdateRequest request=new UpdateRequest("ljx666","6");
User user =new User("GoGo",21,new String[]{"內(nèi)卷","吃飯"});
//將創(chuàng)建的對(duì)象放入文檔中
request.doc(JSONValue.toJSONString(user),XContentType.JSON);
UpdateResponse updateResponse=restHighLevelClient.update(request,RequestOptions.DEFAULT);
System.out.println(updateResponse.status());//更新成功返回OK
}
刪除文檔:
@Test
void testDeleteUser() throws IOException {
//創(chuàng)建刪除請(qǐng)求雕旨,指定要?jiǎng)h除的索引與文檔ID
DeleteRequest request=new DeleteRequest("ljx666","6");
DeleteResponse updateResponse=restHighLevelClient.delete(request,RequestOptions.DEFAULT);
System.out.println(updateResponse.status());//刪除成功返回OK扮匠,沒(méi)有找到返回NOT_FOUND
}
1.3.3 批量CRUD數(shù)據(jù)
這里只列出了批量插入數(shù)據(jù),其他與此類似
注意
:hasFailures()
方法是返回是否失敗奸腺,即它的值為false
時(shí)說(shuō)明上傳成功
@Test
void testBulkAddUser() throws IOException {
BulkRequest bulkRequest=new BulkRequest();
//設(shè)置超時(shí)
bulkRequest.timeout("10s");
ArrayList<User> list=new ArrayList<>();
list.add(new User("Java",25,new String[]{"內(nèi)卷"}));
list.add(new User("Go",18,new String[]{"內(nèi)卷"}));
list.add(new User("C",30,new String[]{"內(nèi)卷"}));
list.add(new User("C++",26,new String[]{"內(nèi)卷"}));
list.add(new User("Python",20,new String[]{"內(nèi)卷"}));
int id=1;
//批量處理請(qǐng)求
for (User u :list){
//不設(shè)置id會(huì)生成隨機(jī)id
bulkRequest.add(new IndexRequest("ljx666")
.id(""+(id++))
.source(JSONValue.toJSONString(u),XContentType.JSON));
}
BulkResponse bulkResponse=restHighLevelClient.bulk(bulkRequest,RequestOptions.DEFAULT);
System.out.println(bulkResponse.hasFailures());//是否執(zhí)行失敗,false為執(zhí)行成功
}
1.3.4 查詢所有餐禁、模糊查詢、分頁(yè)查詢突照、排序、高亮顯示
@Test
void testSearch() throws IOException {
SearchRequest searchRequest=new SearchRequest("ljx666");//里面可以放多個(gè)索引
SearchSourceBuilder sourceBuilder=new SearchSourceBuilder();//構(gòu)造搜索條件
//此處可以使用QueryBuilders工具類中的方法
//1.查詢所有
sourceBuilder.query(QueryBuilders.matchAllQuery());
//2.查詢name中含有Java的
sourceBuilder.query(QueryBuilders.multiMatchQuery("java","name"));
//3.分頁(yè)查詢
sourceBuilder.from(0).size(5);
//4.按照score正序排列
//sourceBuilder.sort(SortBuilders.scoreSort().order(SortOrder.ASC));
//5.按照id倒序排列(score會(huì)失效返回NaN)
//sourceBuilder.sort(SortBuilders.fieldSort("_id").order(SortOrder.DESC));
//6.給指定字段加上指定高亮樣式
HighlightBuilder highlightBuilder=new HighlightBuilder();
highlightBuilder.field("name").preTags("<span style='color:red;'>").postTags("</span>");
sourceBuilder.highlighter(highlightBuilder);
searchRequest.source(sourceBuilder);
SearchResponse searchResponse=restHighLevelClient.search(searchRequest,RequestOptions.DEFAULT);
//獲取總條數(shù)
System.out.println(searchResponse.getHits().getTotalHits().value);
//輸出結(jié)果數(shù)據(jù)(如果不設(shè)置返回條數(shù)氧吐,大于10條默認(rèn)只返回10條)
SearchHit[] hits=searchResponse.getHits().getHits();
for(SearchHit hit :hits){
System.out.println("分?jǐn)?shù):"+hit.getScore());
Map<String,Object> source=hit.getSourceAsMap();
System.out.println("index->"+hit.getIndex());
System.out.println("id->"+hit.getId());
for(Map.Entry<String,Object> s:source.entrySet()){
System.out.println(s.getKey()+"--"+s.getValue());
}
}
}
1.4 高階用法
1.4.1 精確查詢
1.4.1.1 單條件精確查詢
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ElasticSearchApplication.class)
public class SearchJunit {
@Autowired
private RestHighLevelClient client;
/**
* 單條件精確查詢
* @throws IOException
*/
@Test
public void search0() throws IOException {
// 創(chuàng)建請(qǐng)求
SearchSourceBuilder builder = new SearchSourceBuilder()
.query(QueryBuilders.termsQuery("name", "趙里"));
//搜索
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("cs_index");
searchRequest.types("_doc");
searchRequest.source(builder);
// 執(zhí)行請(qǐng)求
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
// 解析查詢結(jié)果
System.out.println(response.toString());
}
}
1.4.1.2 根據(jù) id 精確匹配
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ElasticSearchApplication.class)
public class SearchJunit {
@Autowired
private RestHighLevelClient client;
/**
* 根據(jù)id精確匹配
* @throws IOException
*/
@Test
public void searchById() throws IOException {
String[] ids = new String[]{"1","2"};
// 創(chuàng)建請(qǐng)求
SearchSourceBuilder builder = new SearchSourceBuilder()
.query(QueryBuilders.termsQuery("_id", ids));
//搜索
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("cs_index");
searchRequest.types("_doc");
searchRequest.source(builder);
// 執(zhí)行請(qǐng)求
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
// 解析查詢結(jié)果
System.out.println(response.toString());
}
}
1.4.2 多條件精確查詢讹蘑,取并集
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ElasticSearchApplication.class)
public class SearchJunit {
@Autowired
private RestHighLevelClient client;
/**
* 多條件精確查詢末盔,取并集
* @throws IOException
*/
@Test
public void search1() throws IOException {
// 創(chuàng)建請(qǐng)求
SearchSourceBuilder builder = new SearchSourceBuilder()
.query(QueryBuilders.termsQuery("name", "張", "陳"));
//搜索
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("cs_index");
searchRequest.types("_doc");
searchRequest.source(builder);
// 執(zhí)行請(qǐng)求
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
// 解析查詢結(jié)果
System.out.println(response.toString());
}
}
1.4.3 范圍查詢
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ElasticSearchApplication.class)
public class SearchJunit {
@Autowired
private RestHighLevelClient client;
/**
* 范圍查詢,包括from座慰、to
* @throws IOException
*/
@Test
public void search2() throws IOException {
// 創(chuàng)建請(qǐng)求
SearchSourceBuilder builder = new SearchSourceBuilder()
.query(QueryBuilders.rangeQuery("age").from(20).to(32));
//搜索
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("cs_index");
searchRequest.types("_doc");
searchRequest.source(builder);
// 執(zhí)行請(qǐng)求
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
// 解析查詢結(jié)果
System.out.println(response.toString());
}
/**
* 范圍查詢陨舱,不包括from、to
* @throws IOException
*/
@Test
public void search3() throws IOException {
// 創(chuàng)建請(qǐng)求
SearchSourceBuilder builder = new SearchSourceBuilder()
.query(QueryBuilders.rangeQuery("age").from(20,false).to(30, false));
//搜索
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("cs_index");
searchRequest.types("_doc");
searchRequest.source(builder);
// 執(zhí)行請(qǐng)求
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
// 解析查詢結(jié)果
System.out.println(response.toString());
}
/**
* 范圍查詢, lt:小于版仔,gt:大于
* @throws IOException
*/
@Test
public void search4() throws IOException {
// 創(chuàng)建請(qǐng)求
SearchSourceBuilder builder = new SearchSourceBuilder()
.query(QueryBuilders.rangeQuery("age").lt(30).gt(20));
//搜索
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("cs_index");
searchRequest.types("_doc");
searchRequest.source(builder);
// 執(zhí)行請(qǐng)求
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
// 解析查詢結(jié)果
System.out.println(response.toString());
}
}
1.4.4 模糊查詢游盲,支持通配符
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ElasticSearchApplication.class)
public class SearchJunit {
@Autowired
private RestHighLevelClient client;
/**
* 模糊查詢,支持通配符
* @throws IOException
*/
@Test
public void search5() throws IOException {
// 創(chuàng)建請(qǐng)求
SearchSourceBuilder builder = new SearchSourceBuilder()
.query(QueryBuilders.wildcardQuery("name","張三"));
//搜索
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("cs_index");
searchRequest.types("_doc");
searchRequest.source(builder);
// 執(zhí)行請(qǐng)求
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
// 解析查詢結(jié)果
System.out.println(response.toString());
}
}
1.4.5 不使用通配符的模糊查詢蛮粮,左右匹配
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ElasticSearchApplication.class)
public class SearchJunit {
@Autowired
private RestHighLevelClient client;
/**
* 不使用通配符的模糊查詢益缎,左右匹配
* @throws IOException
*/
@Test
public void search6() throws IOException {
// 創(chuàng)建請(qǐng)求
SearchSourceBuilder builder = new SearchSourceBuilder()
.query(QueryBuilders.queryStringQuery("張三").field("name"));
//搜索
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("cs_index");
searchRequest.types("_doc");
searchRequest.source(builder);
// 執(zhí)行請(qǐng)求
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
// 解析查詢結(jié)果
System.out.println(response.toString());
}
}
1.4.6 多字段模糊查詢
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ElasticSearchApplication.class)
public class SearchJunit {
@Autowired
private RestHighLevelClient client;
/**
* 多字段模糊查詢
* @throws IOException
*/
@Test
public void search7() throws IOException {
// 創(chuàng)建請(qǐng)求
SearchSourceBuilder builder = new SearchSourceBuilder()
.query(QueryBuilders.multiMatchQuery("長(zhǎng)", "name", "city"));
//搜索
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("cs_index");
searchRequest.types("_doc");
searchRequest.source(builder);
// 執(zhí)行請(qǐng)求
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
// 解析查詢結(jié)果
System.out.println(response.toString());
}
}
1.4.7 分頁(yè)+排序 查詢
1.4.7.1 分頁(yè)
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ElasticSearchApplication.class)
public class SearchJunit {
@Autowired
private RestHighLevelClient client;
/**
* 分頁(yè)搜索
* @throws IOException
*/
@Test
public void search8() throws IOException {
// 創(chuàng)建請(qǐng)求
SearchSourceBuilder builder = new SearchSourceBuilder()
.from(0).size(2);
//搜索
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("cs_index");
searchRequest.types("_doc");
searchRequest.source(builder);
// 執(zhí)行請(qǐng)求
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
// 解析查詢結(jié)果
System.out.println(response.toString());
}
}
1.4.7.2 排序查詢
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ElasticSearchApplication.class)
public class SearchJunit {
@Autowired
private RestHighLevelClient client;
/**
* 排序,字段的類型必須是:integer然想、double莺奔、long或者keyword
* @throws IOException
*/
@Test
public void search9() throws IOException {
// 創(chuàng)建請(qǐng)求
SearchSourceBuilder builder = new SearchSourceBuilder()
.sort("createTime", SortOrder.ASC);
//搜索
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("cs_index");
searchRequest.types("_doc");
searchRequest.source(builder);
// 執(zhí)行請(qǐng)求
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
// 解析查詢結(jié)果
System.out.println(response.toString());
}
}
1.4.7.3 分頁(yè)+排序
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ElasticSearchApplication.class)
public class SearchJunit {
@Autowired
private RestHighLevelClient client;
/**
* 多條件查詢 + 排序 + 分頁(yè)
* @throws IOException
*/
@Test
public void search29() throws IOException {
// 創(chuàng)建請(qǐng)求
SearchSourceBuilder builder = new SearchSourceBuilder();
//條件搜索
BoolQueryBuilder boolQueryBuilder=new BoolQueryBuilder();
boolQueryBuilder.must(QueryBuilders.matchQuery("name", "張王"));
boolQueryBuilder.must(QueryBuilders.rangeQuery("age").lte(30).gte(20));
builder.query(boolQueryBuilder);
//結(jié)果集合分頁(yè)
builder.from(0).size(2);
//排序
builder.sort("createTime",SortOrder.ASC);
//搜索
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("cs_index");
searchRequest.types("_doc");
searchRequest.source(builder);
// 執(zhí)行請(qǐng)求
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
// 解析查詢結(jié)果
System.out.println(response.toString());
}
}
1.4.8 精確統(tǒng)計(jì)篩選文檔數(shù)
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ElasticSearchApplication.class)
public class SearchJunit {
@Autowired
private RestHighLevelClient client;
/**
* 精確統(tǒng)計(jì)篩選文檔數(shù),查詢性能有所降低
* @throws IOException
*/
@Test
public void search10() throws IOException {
// 創(chuàng)建請(qǐng)求
SearchSourceBuilder builder = new SearchSourceBuilder()
.trackTotalHits(true);
//搜索
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("cs_index");
searchRequest.types("_doc");
searchRequest.source(builder);
// 執(zhí)行請(qǐng)求
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
// 解析查詢結(jié)果
System.out.println(response.toString());
}
}
1.4.9 設(shè)置源字段過(guò)濾返回
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ElasticSearchApplication.class)
public class SearchJunit {
@Autowired
private RestHighLevelClient client;
/**
* 設(shè)置源字段過(guò)慮,第一個(gè)參數(shù)結(jié)果集包括哪些字段,第二個(gè)參數(shù)表示結(jié)果集不包括哪些字段
* @throws IOException
*/
@Test
public void search11() throws IOException {
// 創(chuàng)建請(qǐng)求
SearchSourceBuilder builder = new SearchSourceBuilder()
.fetchSource(new String[]{"name","age","city","createTime"},new String[]{});
//搜索
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("cs_index");
searchRequest.types("_doc");
searchRequest.source(builder);
// 執(zhí)行請(qǐng)求
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
// 解析查詢結(jié)果
System.out.println(response.toString());
}
}
1.4.10 match 搜索匹配
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ElasticSearchApplication.class)
public class SearchJunit {
@Autowired
private RestHighLevelClient client;
/**
* match搜索匹配
* @throws IOException
*/
@Test
public void search22() throws IOException {
// 創(chuàng)建請(qǐng)求
SearchSourceBuilder builder = new SearchSourceBuilder()
.query(QueryBuilders.matchQuery("name", "張王"));
//搜索
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("cs_index");
searchRequest.types("_doc");
searchRequest.source(builder);
// 執(zhí)行請(qǐng)求
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
// 解析查詢結(jié)果
System.out.println(response.toString());
}
}
1.4.11 bool組合查詢
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ElasticSearchApplication.class)
public class SearchJunit {
@Autowired
private RestHighLevelClient client;
/**
* bool組合查詢
* @throws IOException
*/
@Test
public void search23() throws IOException {
// 創(chuàng)建請(qǐng)求
SearchSourceBuilder builder = new SearchSourceBuilder();
BoolQueryBuilder boolQueryBuilder=new BoolQueryBuilder();
boolQueryBuilder.must(QueryBuilders.matchQuery("name", "張王"));
boolQueryBuilder.must(QueryBuilders.rangeQuery("age").lte(30).gte(20));
builder.query(boolQueryBuilder);
//搜索
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("cs_index");
searchRequest.types("_doc");
searchRequest.source(builder);
// 執(zhí)行請(qǐng)求
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
// 解析查詢結(jié)果
System.out.println(response.toString());
}
}
1.4.12 nested 類型嵌套查詢
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ElasticSearchApplication.class)
public class SearchJunit {
@Autowired
private RestHighLevelClient client;
/**
* nested類型嵌套查詢
* @throws IOException
*/
@Test
public void search24() throws IOException {
// 創(chuàng)建請(qǐng)求
SearchSourceBuilder builder = new SearchSourceBuilder();
//條件查詢
BoolQueryBuilder mainBool=new BoolQueryBuilder();
mainBool.must(QueryBuilders.matchQuery("name", "趙六"));
//nested類型嵌套查詢
BoolQueryBuilder boolQueryBuilder=new BoolQueryBuilder();
boolQueryBuilder.must(QueryBuilders.matchQuery("products.brand", "A"));
boolQueryBuilder.must(QueryBuilders.matchQuery("products.title", "巧克力"));
NestedQueryBuilder nested = QueryBuilders.nestedQuery("products",boolQueryBuilder, ScoreMode.None);
mainBool.must(nested);
builder.query(mainBool);
//搜索
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("cs_index");
searchRequest.types("_doc");
searchRequest.source(builder);
// 執(zhí)行請(qǐng)求
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
// 解析查詢結(jié)果
System.out.println(response.toString());
}
}
1.4.13 聚合查詢
1.4.13.1 求和
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ElasticSearchApplication.class)
public class SearchJunit {
@Autowired
private RestHighLevelClient client;
/**
* 聚合查詢 sum
* @throws IOException
*/
@Test
public void search30() throws IOException {
// 創(chuàng)建請(qǐng)求
SearchSourceBuilder builder = new SearchSourceBuilder();
//條件搜索
builder.query(QueryBuilders.matchAllQuery());
//聚合查詢
AggregationBuilder aggregation = AggregationBuilders.sum("sum_age").field("age");
builder.aggregation(aggregation);
//搜索
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("cs_index");
searchRequest.types("_doc");
searchRequest.source(builder);
// 執(zhí)行請(qǐng)求
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
// 解析查詢結(jié)果
System.out.println(response.toString());
}
}
1.4.13.2 求平均值
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ElasticSearchApplication.class)
public class SearchJunit {
@Autowired
private RestHighLevelClient client;
/**
* 聚合查詢 avg
* @throws IOException
*/
@Test
public void search31() throws IOException {
// 創(chuàng)建請(qǐng)求
SearchSourceBuilder builder = new SearchSourceBuilder();
//條件搜索
builder.query(QueryBuilders.matchAllQuery());
//聚合查詢
AggregationBuilder aggregation = AggregationBuilders.avg("avg_age").field("age");
builder.aggregation(aggregation);
//搜索
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("cs_index");
searchRequest.types("_doc");
searchRequest.source(builder);
// 執(zhí)行請(qǐng)求
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
// 解析查詢結(jié)果
System.out.println(response.toString());
}
}
1.4.13.3 計(jì)數(shù)
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ElasticSearchApplication.class)
public class SearchJunit {
@Autowired
private RestHighLevelClient client;
/**
* 聚合查詢 count
* @throws IOException
*/
@Test
public void search32() throws IOException {
// 創(chuàng)建請(qǐng)求
SearchSourceBuilder builder = new SearchSourceBuilder();
//條件搜索
builder.query(QueryBuilders.matchAllQuery());
//聚合查詢
AggregationBuilder aggregation = AggregationBuilders.count("count_age").field("age");
builder.aggregation(aggregation);
//搜索
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("cs_index");
searchRequest.types("_doc");
searchRequest.source(builder);
// 執(zhí)行請(qǐng)求
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
// 解析查詢結(jié)果
System.out.println(response.toString());
}
}
1.4.13.4 分組
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ElasticSearchApplication.class)
public class SearchJunit {
@Autowired
private RestHighLevelClient client;
/**
* 聚合查詢 分組
* @throws IOException
*/
@Test
public void search33() throws IOException {
// 創(chuàng)建請(qǐng)求
SearchSourceBuilder builder = new SearchSourceBuilder();
//條件搜索
builder.query(QueryBuilders.matchAllQuery());
//聚合查詢
AggregationBuilder aggregation = AggregationBuilders.terms("tag_createTime").field("createTime")
.subAggregation(AggregationBuilders.count("count_age").field("age")) //計(jì)數(shù)
.subAggregation(AggregationBuilders.sum("sum_age").field("age")) //求和
.subAggregation(AggregationBuilders.avg("avg_age").field("age")); //求平均值
builder.aggregation(aggregation);
//不輸出原始數(shù)據(jù)
builder.size(0);
//搜索
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("cs_index");
searchRequest.types("_doc");
searchRequest.source(builder);
// 執(zhí)行請(qǐng)求
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
// 解析查詢結(jié)果
System.out.println(response.toString());
}
}
參考鏈接:https://mp.weixin.qq.com/s/F-eleu11MZLDiGpHfECdRg
1.5 總結(jié)
- 大致流程
創(chuàng)建對(duì)應(yīng)的請(qǐng)求 --> 設(shè)置請(qǐng)求(添加規(guī)則变泄,添加數(shù)據(jù)等) --> 執(zhí)行對(duì)應(yīng)的方法(傳入請(qǐng)求令哟,默認(rèn)請(qǐng)求選項(xiàng))–> 接收響應(yīng)結(jié)果(執(zhí)行方法返回值)–> 輸出響應(yīng)結(jié)果中需要的數(shù)據(jù)(source,status等) - 注意事項(xiàng)
如果不指定id
妨蛹,會(huì)自動(dòng)生成一個(gè)隨機(jī)id
正常情況下屏富,不應(yīng)該這樣使用new IndexRequest(“l(fā)jx777”)
,如果索引發(fā)生改變了蛙卤,那么代碼都需要修改狠半,可以定義一個(gè)枚舉類或者一個(gè)專門存放常量的類,將變量用final static等進(jìn)行修飾表窘,并指定索引值典予。其他地方引用該常量即可,需要修改也只需修改該類即可乐严。
elasticsearch
相關(guān)的東西瘤袖,版本都必須一致,不然會(huì)報(bào)錯(cuò)
elasticsearch
很消耗內(nèi)存昂验,建議在內(nèi)存較大的服務(wù)器上運(yùn)行elasticsearch
捂敌,否則會(huì)因?yàn)閮?nèi)存不足導(dǎo)致elasticsearch自動(dòng)killed
轉(zhuǎn)載于:https://mp.weixin.qq.com/s/G8x18bvHQz60gGu1YiRJ5w