赞
踩
springboot与elasticsearch的更新都非常快,为了避免兼容性问题,要注意下选择的版本问题。具体的可参考官网 --> springboot与elasticsearch版本兼容性
- <dependencies>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
- <version>2.7.18</version>
- </dependency>
- <dependency>
- <groupId>jakarta.json</groupId>
- <artifactId>jakarta.json-api</artifactId>
- <version>2.0.1</version>
- </dependency>
- </dependencies>
-
- spring.elasticsearch.rest.uris=http://localhost:9200
- spring.elasticsearch.rest.username=dev
- spring.elasticsearch.rest.password=123456
- import lombok.Data;
- import org.springframework.data.annotation.Id;
- import org.springframework.data.elasticsearch.annotations.Document;
- import org.springframework.data.elasticsearch.annotations.Field;
- import org.springframework.data.elasticsearch.annotations.FieldType;
-
-
- @Document(indexName = "employee")
- @Data
- public class Employee {
-
- @Id
- private int id;
-
- @Field(name = "name")
- private String name;
-
- @Field(name = "addr", type = FieldType.Keyword)
- private String addr;
-
- }
该实体类加上@Document注解之后,程序启动后就会自动向ED发送创建索引的请求(若没有则创建)。
- import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
-
- public interface EmployeeRepository extends ElasticsearchRepository<Employee, Integer> {
- }
使用该接口可方便对索引进行增删查改。例子比较简单,我们直接写个单元测试。代码如下:
- import gamecontext.admin.elasticsearch.Employee;
- import gamecontext.admin.elasticsearch.EmployeeRepository;
- import org.junit.Assert;
- 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;
-
- @SpringBootTest()
- @RunWith(SpringRunner.class)
- public class ElasticsearchTest {
-
- @Autowired
- private EmployeeRepository repository;
-
- @Test
- public void testSave() {
- Employee p = new Employee();
- p.setId(3);
- p.setAddr("北京");
- p.setName("Tim");
- repository.save(p);
- Assert.assertEquals("Tim", repository.findById(3).get().getName());
- }
-
- @Test
- public void testDelete() {
- Employee p = new Employee();
- p.setId(4);
- p.setAddr("北京");
- p.setName("Tim");
- repository.save(p);
- repository.deleteById(4);
- Assert.assertFalse(repository.findById(4).isPresent());
- }
-
- @Test
- public void testUpdate() {
- Employee p = repository.findById(3).get();
- p.setName("南京");
- repository.save(p);
- Assert.assertEquals(repository.findById(3).get().getName(), "南京");
- }
-
- }
ElasticsearchRepository只能对文档进行简单的增删查改,如果遇到复杂的全文搜索,则需要借助QueryBuilder和ElasticsearchRestTemplate相关API
往索引插入3条文档,数据如下
- import gamecontext.admin.elasticsearch.Employee;
- import gamecontext.admin.elasticsearch.EmployeeRepository;
- import org.elasticsearch.index.query.BoolQueryBuilder;
- import org.elasticsearch.index.query.QueryBuilders;
- import org.junit.Assert;
- 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.data.elasticsearch.core.ElasticsearchRestTemplate;
- import org.springframework.data.elasticsearch.core.SearchHits;
- import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
- import org.springframework.test.context.junit4.SpringRunner;
-
- @SpringBootTest()
- @RunWith(SpringRunner.class)
- public class ElasticsearchTest2 {
-
- @Autowired
- private ElasticsearchRestTemplate elasticsearchRestTemplate;
-
- @Test
- public void testMust() {
- NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
- BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
- boolQueryBuilder.must(QueryBuilders.matchQuery("name", "李"))
- .must(QueryBuilders.matchQuery("name", "四"));
- nativeSearchQueryBuilder.withQuery(boolQueryBuilder);
-
- SearchHits<Employee> hits = elasticsearchRestTemplate.search(nativeSearchQueryBuilder.build(), Employee.class);
- Assert.assertTrue(hits.stream().findFirst().isPresent());
- Assert.assertEquals(hits.stream().findFirst().get().getContent().getName(), "李四");
- }
- }
等效的Kibana命令
- @Test
- public void testRange() {
- NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
- RangeQueryBuilder builder = QueryBuilders.rangeQuery("age").lte(20).gte(10);
- nativeSearchQueryBuilder.withQuery(builder);
- SearchHits<Employee> hits = elasticsearchRestTemplate.search(nativeSearchQueryBuilder.build(), Employee.class);
- Assert.assertEquals(2, hits.getTotalHits());
- }
等效的Kibana命令
- @Test
- public void testSort() {
- NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
- nativeSearchQueryBuilder.withQuery(QueryBuilders.matchAllQuery());
- nativeSearchQueryBuilder.withSort(SortBuilders.fieldSort("age").order(SortOrder.DESC));
- // .withSort(SortBuilders.fieldSort("name").order(SortOrder.ASC));
- SearchHits<Employee> hits = elasticsearchRestTemplate.search(nativeSearchQueryBuilder.build(), Employee.class);
- Employee p1 = hits.stream().findFirst().get().getContent();
- List<SearchHit<Employee>> list = hits.stream().collect(Collectors.toUnmodifiableList());
- Assert.assertTrue(list.get(0).getContent().getAge()>list.get(1).getContent().getAge());
- Assert.assertTrue(list.get(1).getContent().getAge()>list.get(2).getContent().getAge());
- }
等效的Kibana命令
默认情况下,text类型的字段是不能排序的,否则会报以下异常,
Caused by: ElasticsearchException[Elasticsearch exception [type=illegal_argument_exception, reason=Text fields are not optimised for operations that require per-document field data like aggregations and sorting, so these operations are disabled by default. Please use a keyword field instead. Alternatively, set fielddata=true on [name] in order to load field data by uninverting the inverted index. Note that this can use significant memory.]]
翻译如下:
默认情况下,文本字段禁用字段数据。在[region]上设置fielddata=true,以便通过取消反转索引将fielddata加载到内存中。请注意,这可能会占用大量内存。
解决方法:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。