准备
把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;
}
}