SpringBoot integrates ElasticSearch to realize fuzzy query, batch CRUD, sorting, paging, highlighting

Preparation

Prepare an empty SpringBoot project

write dependencies

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>

Note that your SpringBoot and your es version must correspond. If you don’t know, you can check this article: https://blog.csdn.net/u014641168/article/details/130386872

My version is 2.2.6, so the ES version used is 6.8.12, please see this article to install es: https://blog.csdn.net/u014641168/article/details/130622430
insert image description here
View ES version
insert image description here
insert image description here

configuration

Create an ES configuration file, there are 2 beans below, one is that your ES has an account password, and the other is not by default.

package cn.ityao.es.config;

import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @Author tongyao
 */
@Configuration
public class ElasticsearchConfig {
    
    
    @Value("${
    
    elasticsearch.port}")
    private int port;

    @Value("${
    
    elasticsearch.ip}")
    private String ip;

    @Value("${
    
    elasticsearch.username}")
    private String username;

    @Value("${
    
    elasticsearch.password}")
    private String password;

    /**
     * 创建带HTTP Basic Auth认证rest客户端
     */
    @Bean
    public RestHighLevelClient restHighLevelClient() {
    
    
        CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
        credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username, password));
        return new RestHighLevelClient(RestClient.builder(
                new HttpHost[]{
    
    
                    new HttpHost(ip, port, "http")
                }).setHttpClientConfigCallback((HttpAsyncClientBuilder httpAsyncClientBuilder) -> httpAsyncClientBuilder.setDefaultCredentialsProvider(credentialsProvider)));
    }

    //不带用户名密码验证
    //@Bean
    public RestHighLevelClient restClient() {
    
    
        return new RestHighLevelClient(RestClient.builder(new HttpHost[]{
    
    
                new HttpHost(ip, port, "http")
        }));
    }
}

yml configuration file content

server:
  # 服务端口
  port: 9990

elasticsearch:
  port: 9200
  ip: 127.0.0.1
  username: elastic
  password: 123456


# 查看es信息时需要的序列化
spring:
  jackson:
    serialization:
      FAIL_ON_EMPTY_BEANS: false

inject dependencies

Inject dependencies under the controller

@Autowired
private RestHighLevelClient restHighLevelClient;

CURD on the index

1. Create an index

/**
 * 创建索引
 *
 * @return
 * @throws IOException
 */
@GetMapping("/createIndex")
public Object createIndex() throws IOException {
    
    
	//1.创建索引请求
	CreateIndexRequest request = new CreateIndexRequest("testindex");
	//2.客户端执行请求IndicesClient,执行create方法创建索引,请求后获得响应
	CreateIndexResponse response =
			restHighLevelClient.indices().create(request, RequestOptions.DEFAULT);
	return response;
}

insert image description here
You can see that it has been added successfully, but be careful, the index name must be lowercase!

2. Query index

/**
 * 查询索引
 *
 * @return
 * @throws IOException
 */
@GetMapping("/searchIndex")
public Object searchIndex() throws IOException {
    
    
	//1.查询索引请求
	GetIndexRequest request = new GetIndexRequest("testindex");
	//2.执行exists方法判断是否存在
	boolean exists = restHighLevelClient.indices().exists(request, RequestOptions.DEFAULT);
	return exists;
}

3. Delete the index

/**
 * 删除索引
 *
 * @return
 * @throws IOException
 */
@GetMapping("delIndex")
public Object delIndex() throws IOException {
    
    
	//1.删除索引请求
	DeleteIndexRequest request = new DeleteIndexRequest("testindex");
	//执行delete方法删除指定索引
	AcknowledgedResponse delete = restHighLevelClient.indices().delete(request, RequestOptions.DEFAULT);
	return delete.isAcknowledged();
}

CRUD to documents

1. New document

Note: If you do not specify a document ID when adding, it will randomly generate an ID, which is unique.

/**
 * 新增文档
 *
 * @return
 * @throws IOException
 */
@GetMapping("/add")
public Object add() throws IOException {
    
    
	//1.创建对象
	User user = new User("张三", 21);
	//2.创建请求(索引的名字)
	IndexRequest request = new IndexRequest("indexdocument");
	//3.设置规则 PUT /ljx666/_doc/1
	//设置文档id=6,设置超时=1s等,不设置会使用默认的
	//同时支持链式编程如 request.id("6").timeout("1s");
	request.id("6");
	// 指定要写入的 Index
	request.type("_doc");
	/*request.index("test");*/
	/*request.timeout(TimeValue.timeValueSeconds(1));*/
	request.timeout("1s");

	//4.将数据放入请求,要将对象转化为json格式
	//XContentType.JSON,告诉它传的数据是JSON类型
	request.source(JSON.toJSONString(user), XContentType.JSON);

	//5.客户端发送请求,获取响应结果
	IndexResponse indexResponse = restHighLevelClient.index(request, RequestOptions.DEFAULT);
	System.out.println(indexResponse.toString());
	System.out.println(indexResponse.status());
	return indexResponse;
}

2. Query the data in the document

/**
 * 获取文档中的数据
 *
 * @return
 * @throws IOException
 */
@GetMapping("/get")
public Object get() throws IOException {
    
    
	//1.创建请求,指定索引、文档id(索引的名字)
	GetRequest request = new GetRequest("indexdocument").id("6").type("_doc");
	GetResponse getResponse = restHighLevelClient.get(request, RequestOptions.DEFAULT);
	System.out.println(getResponse);//获取响应结果
	//getResponse.getSource() 返回的是Map集合
	System.out.println(getResponse.getSourceAsString());//获取响应结果source中内容,转化为字符串
	return getResponse;
}

3. Update the data in the document

Note: You need to specify values ​​for all the attributes in the User object, otherwise they will be set to null. If the User only sets the name, then only the name will be modified successfully, and the others will be modified to null.

/**
 * 更新文档数据
 *
 * @return
 * @throws IOException
 */
@GetMapping("/update")
public Object update() throws IOException {
    
    
	//1.创建请求,指定索引、文档id(索引的名字)
	UpdateRequest request = new UpdateRequest("indexdocument","_doc","6");

	User user = new User("小明", 21);
	//将创建的对象放入文档中
	request.doc(JSON.toJSONString(user), XContentType.JSON);
	UpdateResponse updateResponse = restHighLevelClient.update(request, RequestOptions.DEFAULT);
	System.out.println(updateResponse.status());//更新成功返回OK
	return updateResponse;
}

3. Delete the data in the document

/**
 * 删除文档数据
 *
 * @return
 * @throws IOException
 */
@GetMapping("/delete")
public Object delete() throws IOException {
    
    
	//1.创建删除文档请求
	DeleteRequest request = new DeleteRequest("indexdocument").id("6").type("_doc");
	DeleteResponse deleteResponse = restHighLevelClient.delete(request, RequestOptions.DEFAULT);
	System.out.println(deleteResponse.status());//更新成功返回OK
	return deleteResponse;
}

4. Add data in the document in batches

/**
 * 批量新增文档数据
 *
 * @return
 * @throws IOException
 */
@GetMapping("/addBatch")
public Object addBatch() throws IOException {
    
    
	BulkRequest bulkRequest = new BulkRequest();
	//设置超时
	bulkRequest.timeout("10s");

	List<User> list = new ArrayList<>();
	list.add(new User("李四", 25));
	list.add(new User("王五", 18));
	list.add(new User("赵六", 30));
	list.add(new User("田七", 26));
	list.add(new User("刘八", 20));

	int id = 1;
	//批量处理请求
	for (User user : list) {
    
    
		//不设置id会生成随机id
		bulkRequest.add(new IndexRequest("indexdocument")
				.id("" + (id++))
				.type("_doc")
				.source(JSON.toJSONString(user), XContentType.JSON));
	}

	BulkResponse bulkResponse = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
	System.out.println(bulkResponse.hasFailures());//是否执行失败,false为执行成功
	return bulkResponse;
}

5. Query all, fuzzy query, paging query, sorting, highlighting

/**
 * 复杂的es查询
 * @return
 * @throws IOException
 */
@GetMapping("test")
public Object test() throws IOException {
    
    
	SearchRequest searchRequest = new SearchRequest("indexdocument");//里面可以放多个索引
	SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();//构造搜索条件
	//此处可以使用QueryBuilders工具类中的方法
	//1.查询所有
	sourceBuilder.query(QueryBuilders.matchAllQuery());
	//2.查询name中含有Java的
	sourceBuilder.query(QueryBuilders.multiMatchQuery("张三", "name"));
	//3.分页查询
	sourceBuilder.from(0).size(5);
	//4.按照score正序排列
	sourceBuilder.sort(SortBuilders.scoreSort().order(SortOrder.ASC));
	//5.按照id倒序排列(score会失效返回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);
	//获取总条数
	System.out.println(searchResponse.getHits().getTotalHits());
	//输出结果数据(如果不设置返回条数,大于10条默认只返回10条)
	SearchHit[] hits = searchResponse.getHits().getHits();
	for (SearchHit hit : hits) {
    
    
		System.out.println("分数:" + 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());
		}
	}
	return searchResponse;
}

Summarize

1. General process

Create the corresponding request --> set the request (add rules, add data, etc.) --> execute the corresponding method (incoming request, default request option) --> receive the response result (execute method return value) --> output the data required in the response result (source, status, etc.)

2. Precautions

If no id is specified, a random id will be automatically generated

Under normal circumstances, new IndexRequest("indexName") should not be used like this. If the index changes, the code needs to be modified. You can define an enumeration class or a class that stores constants, modify the variable with final static, etc., and specify the index value. You can refer to this constant elsewhere, and you only need to modify this class if you need to modify it.

Elasticsearch-related things, the version must be consistent, otherwise an error will be reported

Elasticsearch consumes a lot of memory. It is recommended to run elasticsearch on a server with a large memory, otherwise elasticsearch will be automatically killed due to insufficient memory

Article reference: https://blog.csdn.net/zhiyikeji/article/details/128902860

Guess you like

Origin blog.csdn.net/u014641168/article/details/130687535