1, ElasticsearchRestTemplate
Previously, I learned how the es rest interface operates es, and also learned the fragmentation and capacity expansion of ES. I explained several common word splitters. If you like, you can see other articles in this column. This article will mainly use ElasticsearchRestTemplate to operate es in SpringBoot.
I wrote an article on the operation of SpringBoot on ES long ago, but it was based on ES 6 X is not recommended in the new version of ES.
Note: some online tutorials use TransportClient for operation. TransportClient is not recommended in Elasticsearch 7.0, and TransportClient will be completely deleted in 8.0. Therefore, the official recommends that we use the Java High Level REST Client, which executes HTTP requests rather than serialized Java requests.
The ElasticsearchRestTemplate we use is another layer of encapsulation based on RestHighLevelClient. Let's start together.
2, SpringBoot integrates ES client environment
First, create a new SpringBoot project, and then introduce es dependency into pom:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency>
In application In the YML configuration file, configure the connection of es:
server: port: 8080 spring: elasticsearch: rest: uris: http://127.0.0.1:9200 # multiple addresses are separated by commas # username: #user name # password: #password connection-timeout: 6000 read-timeout: 6000
Now that the environment has been set up, let's start to operate es.
3, ElasticsearchRestTemplate operation ES
First, create an ES entity class:
@Data @NoArgsConstructor @AllArgsConstructor @Document(indexName = "user", shards = 3, replicas = 1, refreshInterval = "30s") public class UserEsEntity { @Id private String id; @Field(type = FieldType.Text, searchAnalyzer = "ik_max_word", analyzer = "ik_smart") private String name; @Field(type = FieldType.Keyword) private String sex; @Field(type = FieldType.Integer) private Integer age; @Field(type = FieldType.Keyword, index = false) private String grade; }
The defined index name is user, the partition is 3, the copy of each partition is 1, and the refresh time is 30s.
Next, you can create an ElasticsearchRepository. In fact, you can directly use ElasticsearchRestTemplate to operate es, and many methods in the Repository are marked obsolete. Here you can also see:
@Repository public interface UserEsDao extends ElasticsearchRepository<UserEsEntity, Long> { }
ElasticsearchRepository is no longer recommended for queries. Let's learn the Api of ElasticsearchRestTemplate directly.
1. Judge whether the index exists
In fact, the Entity is written above. If the index does not exist, it will be created automatically. Here, you can also verify it through Api:
@Slf4j @RestController @RequestMapping("/rest") public class RestTemplateController { @Autowired ElasticsearchRestTemplate elasticsearchRestTemplate; @GetMapping("/indexExists") public String indexExists() { boolean r1 = elasticsearchRestTemplate.indexExists(UserEsEntity.class); boolean r2 = elasticsearchRestTemplate.indexExists("user2"); // Create index // elasticsearchRestTemplate.createIndex() log.info("r1: {} , r2: {}", r1, r2); return "success"; } }
2. Add document data
@GetMapping("/save") public String save() { UserEsEntity esEntity = new UserEsEntity(null, "Zhang San", "male", 18, "1"); // Don't get the self increasing return value // UserEsEntity save = elasticsearchRestTemplate.save(esEntity); // log.info(save.toString()); // Get the self increasing return value IndexQuery indexQuery = new IndexQueryBuilder() // .withId(esEntity.getId()) .withObject(esEntity) .build(); String id = elasticsearchRestTemplate.index(indexQuery, IndexCoordinates.of("user")); log.info("Added id: {} ", id); // Batch add // List<UserEsEntity> list = new ArrayList<>(); // list.add(esEntity); // list.add(esEntity); // elasticsearchRestTemplate.save(list); return "success"; }
3. Update document data
For batch modification according to conditions, RestHighLevelClient needs to be used, which can be injected directly:
@Autowired RestHighLevelClient restHighLevelClient;
@GetMapping("/update") public String update() throws IOException { // Overwrite modification // Useresentity: esentity = new useresentity ("w9mvd34bvynyxunr8cde", "Lisi", "male", 20, "1"); // elasticsearchRestTemplate.save(esEntity); // UpdateQuery query = UpdateQuery.builder("W9MVD34BVYNyxUnr8cdE"); // Modify a field by ID // Document document = Document.create(); // document.putIfAbsent("name", "wangwu2"); // Updated content // UpdateQuery updateQuery = UpdateQuery.builder("W9MVD34BVYNyxUnr8cdE") // .withDocument(document) // . withRetryOnConflict(5) / / conflict retry // . withDocAsUpsert(true) / / no default false. True indicates to insert when the update does not exist // .build(); // UpdateResponse response = elasticsearchRestTemplate.update(updateQuery, IndexCoordinates.of("user")); // log.info(response.getResult().toString()); //UPDATED indicates that the update was successful // Batch update according to conditions and use RestHighLevelClient // https://blog.csdn.net/weixin_34318272/article/details/88690004 // The parameter is an index name, which can be unspecified, one or more UpdateByQueryRequest request = new UpdateByQueryRequest("user"); // Version conflict request.setConflicts("proceed"); // Set query criteria BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery(); // And and queryBuilder.must(QueryBuilders.termQuery("name", "lisi")); queryBuilder.must(QueryBuilders.termQuery("sex", "male")); request.setQuery(queryBuilder); // Batch size request.setBatchSize(1000); // parallel request.setSlices(2); // Use the scroll parameters to control how long the search context survives request.setScroll(TimeValue.timeValueMinutes(10)); // Refresh index request.setRefresh(true); // Updated content request.setScript(new Script("ctx._source['name']='wangwu'")); BulkByScrollResponse response = restHighLevelClient.updateByQuery(request, RequestOptions.DEFAULT); log.info(response.getStatus().getUpdated() + ""); // A return of 1 indicates success return "success"; }
4. Delete document data
@GetMapping("/delete") public String delete() { // Delete by id // String r = elasticsearchRestTemplate.delete("XNMVD34BVYNyxUnr8cdE", IndexCoordinates.of("user")); // log.info("r : {} ", r); // Delete according to condition BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery(); // And and queryBuilder.must(QueryBuilders.termQuery("name", "zhangsan")); queryBuilder.must(QueryBuilders.termQuery("sex", "male")); Query query = new NativeSearchQuery(queryBuilder); elasticsearchRestTemplate.delete(query, UserEsEntity.class, IndexCoordinates.of("user")); return "success"; }
5. Query document data
@GetMapping("/search") public String search() { // Query all data // QueryBuilder queryBuilder = QueryBuilders.matchAllQuery(); // Precise query= // QueryBuilder queryBuilder = QueryBuilders.termQuery("name", "lisi"); // Accurately query multiple in // QueryBuilder queryBuilder = QueryBuilders.termsQuery("name", "Zhang San", "lisi"); // match matching will segment the query criteria, and then query. Multiple entries have an or relationship, and word segmentation can be specified // QueryBuilder queryBuilder = QueryBuilders.matchQuery("name", "Zhang San"); // QueryBuilder queryBuilder = QueryBuilders.matchQuery("name", "Zhang San") analyzer("ik_max_word"); // match query multiple fields // QueryBuilder queryBuilder = QueryBuilders.multiMatchQuery("male", "name", "sex"); // Fuzzy fuzzy query, which returns documents containing words similar to the search words. // QueryBuilder queryBuilder = QueryBuilders.fuzzyQuery("name","lisx"); // Prefix prefix retrieval // QueryBuilder queryBuilder = QueryBuilders.prefixQuery("name", "Zhang"); // Wildcard wildcard retrieval // QueryBuilder queryBuilder = QueryBuilders.wildcardQuery("name", "Zhang *"); // regexp regular query QueryBuilder queryBuilder = QueryBuilders.regexpQuery("name", "(Zhang San)|(lisi)"); // boost score weight, which makes the score of documents that meet a certain condition higher, so as to make them rank higher. queryBuilder.boost(2); // Multi conditional construction // BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery(); // And and // queryBuilder.must(QueryBuilders.termQuery("name", "Zhang San"); // queryBuilder.must(QueryBuilders.termQuery("sex", "female"); // or // queryBuilder.should(QueryBuilders.termQuery("name", "Zhang San")); // queryBuilder.should(QueryBuilders.termQuery("name", "lisi")); // Not equal to, remove // queryBuilder.mustNot(QueryBuilders.termQuery("name", "lisi")); // Filter data // queryBuilder.filter(QueryBuilders.matchQuery("name", "Zhang San"); // Range query /* gt Greater than > gte Greater than or equal to >= lt Less than< lte Less than or equal to<= */ // queryBuilder.filter(new RangeQueryBuilder("age").gt(10).lte(50)); // Build page, page starts from 0 Pageable pageable = PageRequest.of(0, 3); Query query = new NativeSearchQueryBuilder() .withQuery(queryBuilder) .withPageable(pageable) //sort .withSort(SortBuilders.fieldSort("_score").order(SortOrder.DESC)) //Projection .withFields("name") .build(); SearchHits<UserEsEntity> search = elasticsearchRestTemplate.search(query, UserEsEntity.class); log.info("total: {}", search.getTotalHits()); Stream<SearchHit<UserEsEntity>> searchHitStream = search.get(); List<UserEsEntity> list = searchHitStream.map(SearchHit::getContent).collect(Collectors.toList()); log.info("Number of results:{}", list.size()); list.forEach(entity -> { log.info(entity.toString()); }); return "success"; }
Love little buddy can pay attention to my personal WeChat official account and get more learning materials.