准備
把Elasticsearch安裝好
安裝百度上有很多資料。
導入必要的包
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.3.RELEASE</version>
</parent>
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>4.2.2</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>2.4.6</version>
</dependency>
<dependency>
<groupId>io.searchbox</groupId>
<artifactId>jest</artifactId>
<version>2.0.4</version>
</dependency>
實體類
@Data
public class ArticleDTO implements Serializable {
private Integer id;
private String authorId;
private String articleId;
private String title;
private String content;
private Integer status;
}
Elasticsearch的Search
最好先了解一下:
Elasticsearch的Search詳解
JEST的相關操作
- 發現這個客戶端工具使用了大量的構造器模式。
- 這么多的構造器的抽象都是針對於ES中的概念和查詢語法抽象出來的,所以對ES客戶端的理解要結合查詢語言。
package com.ztjy.es;
import com.ztjy.demo.model.ArticleDTO;
import com.ztjy.demo.service.ArticleService;
import com.ztjy.demo.service.search.JestClientServer;
import com.ztjy.tool.RandomUtils;
import io.searchbox.client.JestClient;
import io.searchbox.client.JestClientFactory;
import io.searchbox.client.JestResult;
import io.searchbox.client.config.HttpClientConfig;
import io.searchbox.core.*;
import io.searchbox.indices.DeleteIndex;
import lombok.extern.log4j.Log4j2;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.TermsBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortOrder;
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.test.context.junit4.SpringRunner;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@RunWith(SpringRunner.class)
@SpringBootTest
@Log4j2
public class TestEs {
public static final String INDEX_NAME = "test_index_ws";
public static final String TYPE_NAME = "my_type";
public static final String TYPE_NAME2 = "my_type2";
public static final String URI = "http://172.16.200.17:9200";
@Autowired
private JestClientServer jestClientServer;
@Autowired
private ArticleService articleService;
//刪除index下的所有
/**
* 創建index/type/document
* <p>單個</p>
*/
@Test
public void testCreateIndex(){
ArticleDTO article = createArticle(1000);
addOrUpdateIndex(article);
}
/**
* 刪除index里面的document全部清除了
*/
@Test
public void testDeleteIndex(){
DeleteIndex deleteIndex = new DeleteIndex.Builder(INDEX_NAME).build();
JestClient jestClient = createClient();
try {
JestResult result = jestClient.execute(deleteIndex);
log.info("執行結果:{}",result.isSucceeded());
log.info("返回記過:{}",result.getSourceAsString());
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 測試修改index
*/
@Test
public void testUpdateIndex(){
ArticleDTO article = createArticle(1000);
article.setTitle(article.getTitle()+"3333!");
addOrUpdateIndex(article);
}
/**
* 測試批量添加index
*/
@Test
public void testBulkIndex(){
bulkIndex();
}
/**
* 測試批量刪除index
*/
@Test
public void testbulkDeleteIndex(){
bulkDeleteIndex();
}
/**
* 刪除單個index
*/
@Test
public void deleteSigleIndex(){
deleteSingeIndex();
}
/**
* 測試獲取單個index
*/
@Test
public void testGetIndex(){
getSingleIndex();
}
/**
* 根據條件,分頁查詢
*
*
*/
@Test
public void testQueryByTypeAndIds(){
QueryByTypeAndIds();
}
@Test
public void testQueryByCnd(){
/**
*{
* "query" : {
* "match" : {//對應着各種類型的QueryBuilder,這里的類型是短語匹配
* "title" : {
* "query" : "寶爸給孩子",
* "type" : "phrase"
* }
* }
* }
* }
* //SearchSourceBuilder對應着查詢json結構的最外層(from,size,query,post_filter,sort,aggs)
* //QueryBuilder對應着各種過濾條件:精確搜索,布爾,范圍
*{
* "from" : 0,
* "size" : 5,
* "query" : {
* "match" : {
* "title" : {
* "query" : "寶爸給孩子",
* "type" : "phrase"
* }
* }
* },
* "post_filter" : {
* "bool" : {
* "must" : [ {
* "term" : {
* "status" : 6
* }
* }, {
* "range" : {
* "id" : {
* "from" : null,
* "to" : 500,
* "include_lower" : true,
* "include_upper" : true
* }
* }
* }, {
* "terms" : {
* "title" : [ "護士" ]
* }
* } ],
* "_name" : "title"
* }
* },
* "sort" : [ {
* "id" : {
* "order" : "desc"
* }
* } ]
* }
*
*
*/
SearchSourceBuilder searchSourceBuilder=new SearchSourceBuilder();
MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("title", "寶爸給孩子");
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery()
.must(QueryBuilders.termQuery("status", 6))
.must(QueryBuilders.rangeQuery("id").lte(500))
.must(QueryBuilders.termsQuery("title","護士"));
searchSourceBuilder.from(0).
size(5).
sort("id", SortOrder.DESC).
postFilter(boolQueryBuilder).
query(matchQueryBuilder);
//聚合
TermsBuilder status = AggregationBuilders.terms("group_by_tatus").field("status");
searchSourceBuilder.aggregation(status);
Search search = new Search.Builder(searchSourceBuilder.toString()).addIndex(INDEX_NAME).addType(TYPE_NAME).build();
JestClient jestClient = createClient();
try {
SearchResult searchResult = jestClient.execute(search);
log.info("執行結果{}",searchResult.isSucceeded());
List<SearchResult.Hit<ArticleDTO, Void>> hitList = searchResult.getHits(ArticleDTO.class);
hitList.stream().map((hit)-> hit.source).forEach((article)->{
System.out.println(article);
});
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 查詢多個type下和指定集合去查詢
*
*/
private void QueryByTypeAndIds() {
SearchSourceBuilder searchSourceBuilder=new SearchSourceBuilder();
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
String [] ids=new String[]{"1","2","3","4","5"};
String [] types=new String[]{TYPE_NAME,TYPE_NAME2};
boolQueryBuilder.must(QueryBuilders.idsQuery(types).addIds(ids));
searchSourceBuilder.query(boolQueryBuilder);
Search search=new Search.Builder(searchSourceBuilder.toString()).build();
JestClient jestClient = createClient();
try {
SearchResult searchResult = jestClient.execute(search);
log.info("執行結果{}",searchResult.isSucceeded());
List<SearchResult.Hit<ArticleDTO, Void>> hitList = searchResult.getHits(ArticleDTO.class);
for (SearchResult.Hit<ArticleDTO, Void> hit:hitList) {
ArticleDTO article = hit.source;
log.info(article);
}
} catch (IOException e) {
e.printStackTrace();
}
}
private void getSingleIndex() {
Get get = new Get.Builder(INDEX_NAME, "23726").type(TYPE_NAME).build();
JestClient jestClient = createClient();
try {
DocumentResult documentResult = jestClient.execute(get);
log.info("執行結果{}",documentResult.isSucceeded());
ArticleDTO articleDTO = documentResult.getSourceAsObject(ArticleDTO.class);
log.info("查詢的值{}",articleDTO.toString());
} catch (IOException e) {
e.printStackTrace();
}
}
private void deleteSingeIndex() {
Delete delete = new Delete.Builder("AW1xUehNzfOadqqIiWnt").index(INDEX_NAME).type(TYPE_NAME).build();
JestClient client = createClient();
try {
DocumentResult documentResult = client.execute(delete);
log.info("是否添加成功:{}",documentResult.isSucceeded());
log.info("結果:{}",documentResult.getJsonString());
} catch (IOException e) {
e.printStackTrace();
}
}
private void bulkDeleteIndex(){
Bulk.Builder bulk = new Bulk.Builder();
List<String> articleIds =new ArrayList<>(100);
articleIds.add("21082");
articleIds.add("21191");
articleIds.add("22053");
articleIds.add("20761");
articleIds.add("21038");
for(String id:articleIds){
Delete delete = new Delete.Builder(id).index(INDEX_NAME).type(TYPE_NAME).build();
bulk.addAction(delete);
}
try {
JestClient jestClient = createClient();
BulkResult result = jestClient.execute(bulk.build());
if (result != null && result.isSucceeded()){
log.info("ES 批量刪除完成");
log.info("=====================>result:{}.",result.getJsonString());
}else{
log.error("=====================>result:{}.",result.getJsonString());
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void addOrUpdateIndex(ArticleDTO article) {
try {
Index.Builder indexBuilder=new Index.Builder(article);
indexBuilder.index(INDEX_NAME).type(TYPE_NAME).id(String.valueOf(article.getId()));
Index index = indexBuilder.build();
JestClient jsClient = createClient();
DocumentResult result = jsClient.execute(index);
log.info("是否添加成功:{}",result.isSucceeded());
log.info("結果:{}",result.getJsonString());
} catch (IOException e) {
e.printStackTrace();
}
}
public void bulkIndex(){
Bulk.Builder bulk = new Bulk.Builder();
List<ArticleDTO> listArticle = getListArticle();
Iterator<ArticleDTO> iterator = listArticle.iterator();
while (iterator.hasNext()){
ArticleDTO article = iterator.next();
Index index = new Index.Builder(article).id(String.valueOf(article.getId())).index(INDEX_NAME).type(TYPE_NAME).build();
bulk.addAction(index);
}
try {
JestClient jestClient = createClient();
BulkResult result = jestClient.execute(bulk.build());
if (result != null && result.isSucceeded()){
log.info("ES 批量插入完成");
log.info("=====================>result:{}.",result.getJsonString());
}else{
log.error("=====================>result:{}.",result.getJsonString());
}
} catch (Exception e) {
e.printStackTrace();
}
}
private ArticleDTO createArticle(int id) {
ArticleDTO articleDTO=new ArticleDTO();
articleDTO.setId(id);
articleDTO.setArticleId(String.valueOf(id*100));
articleDTO.setAuthorId(String.valueOf(id*1000));
articleDTO.setTitle("折騰三天生下9斤男嬰,寶爸給孩子取了88畫名字,護士直接笑哭");
articleDTO.setContent("小靜上個星期剛順產生下一名男嬰,當時這個孩子折騰了她快三天三夜才成功生下來。可把小靜給疼到生無絕戀了,最后孩子出生后足足有9斤重。");
articleDTO.setStatus(RandomUtils.randomInt(10));
return articleDTO;
}
private List<ArticleDTO> getListArticle(){
List<ArticleDTO> articleDTOS=new ArrayList<>(100);
for (int i =0;i<100;i++){
articleDTOS.add(createArticle(i+1));
}
return articleDTOS;
}
private JestClient createClient() {
JestClientFactory factory = new JestClientFactory();
factory.setHttpClientConfig(new HttpClientConfig.Builder(URI)
.multiThreaded(true)
.build());
JestClient client = factory.getObject();
return client;
}
}
