Spring Data Elasticsearch配置及使用
文章目录
- Spring Data Elasticsearch
- Spring Data Elasticsearch访问Elasticsearch
-
- 准备环境
- 索引操作
- 文档操作
Spring Data Elasticsearch
以POJO为中心模型用于与Elastichsearch文档交互,并轻松编写存储库样式的数据访问层框架
我们学习的是底层封装了Rest High Level的ElasticsearchRestTemplate模板类型。需要使用Java API Client(Transport),则应用ElasticsearchTemplate模板类型即可。两种类型中的方法API几乎完全一样,学会了一个,另外一个主要就是配置和类型的区别。当然了,每个不同版本的框架,在方法API上还是有些差异的。
Spring Data Elasticsearch访问Elasticsearch
准备环境
1.导入依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elasticsearch</artifactId></dependency>
2.yml配置
# ElasticsearchRestTemplate客户端的配置
spring:elasticsearch:rest:uris: http://127.0.0.1:9200 # ES服务器所在位置。集群多节点地址用逗号分隔。默认http://localhost:9200
3.创建实体类
* Document - 描述类型和索引的映射。* indexName - 索引名称* shards - 主分片数量。默认值 1。* replicas - 副本分片数量。默认值 1。@Data
@NoArgsConstructor
@AllArgsConstructor
@Document(indexName = "xy_student",shards = 1,replicas = 0)
public class Student {* Id - 当前注解所在字段和主键值一致,没有次注解,则自动生成主键* Field - 当前属性和索引中的字段映射规则。* name - 字段名称。默认和当前类型属性名一致。* type - 字段类型。默认使用FieldType.AUTO。自动识别。* analyzer - 分词器。所有的Text类型字段默认使用standard分词器。* index - 是否创建索引。默认值 true。* format - 如果字段类型是date日期类型。此属性必须配置,用于设置日期格式化规则,使用DateFormat类型中的常量定义。@Id@Field(name="sid",type = FieldType.Integer)private Integer sid;@Field(name="sname",type = FieldType.Text,analyzer = "ik_max_word")private String sname;@Field(name="score",type = FieldType.Double)private Double score;@Field(name="birth",type = FieldType.Date,format = DateFormat.year_month_day)private Date birth;
}
索引操作
@Autowired
private ElasticsearchRestTemplate restTemplate;IndexOperations indexOps = restTemplate.indexOps(Student.class);
1.创建索引
indexOps.create();2.设置映射: 在商业开发中,几乎不会使用框架创建索引或设置映射。因为这是架构或者管理员的工作。且不适合使用代码实现
indexOps.putMapping(indexOps.createMapping());3.删除索引
restTemplate.indexOps(Student.class).delete();
文档操作
简单CURD
1.新增文档
如果索引不存在,新增文档时自动创建索引。但是不使用类上的映射配置,使用默认映射.所以一定要先通过代码进行mapping设置,或直接在elasticsearch中通过命令创建所有field的mapping(推荐)
Student zs = elasticsearchRestTemplate.save(new Student(1, "zs", 0.55, new Date()));
System.out.println(zs);2.批量新增文档ArrayList<Student> students = new ArrayList<>();students.add(new Student(1, "zs", 0.55, new Date()));students.add(new Student(2, "sdf", 0.22, new Date()));students.add(new Student(3, "df", 0.33, new Date()));Iterable<Student> save = elasticsearchRestTemplate.save(students);System.out.println(save.toString());3.主键查询文档
Student student = restTemplate.get("3", Student.class);4.删除文档// 删除类型对应的索引中的指定主键数据,返回删除数据的主键。注意:Elasticsearch中的文档主键都是字符串类型的。String response = restTemplate.delete("1", Student.class);5.更新文档* save方法,可以覆盖同主键数据。全量替换* update更新,部分更新
@Test
public void testUpdate(){UpdateQuery query =UpdateQuery.builder("2").withDocument(Document.parse("{\\"hobbies\\":[\\"郭麒麟\\", \\"郭汾阳\\"]}")).build();UpdateResponse response = restTemplate.update(query, IndexCoordinates.of("stu_index"));System.out.println(response.getResult());
}
query string 查询
@Testvoid contextsxLsoads() {QueryBuilder queryBuilder = QueryBuilders.queryStringQuery("sname:zs");Query query = new NativeSearchQueryBuilder().withQuery(queryBuilder) // 提供具体的条件。.build();SearchHits<Student> hits = elasticsearchRestTemplate.search(query, Student.class);System.out.println("搜索结果数据个数是: " + hits.getTotalHits());for (SearchHit<Student> hit : hits) {// 源数据,就是保存在Elasticsearch中的数据Student content = hit.getContent();System.out.println("源数据:" + content);}}
DSL 查询
1.搜索全部
@Test
public void testMatchAll(){SearchHits<Student> hits = restTemplate.search(new NativeSearchQueryBuilder().withQuery(QueryBuilders.matchAllQuery()).build(), Student.class);for(SearchHit<Student> hit : hits){System.out.println(hit.getContent());}
}
2.match搜索
SearchHits<Student> hits = restTemplate.search(new NativeSearchQueryBuilder().withQuery(QueryBuilders.matchQuery("name","于谦")).build(),Student.clas);3.短语搜索,完全匹配Match PhraseSearchHits<Student> hits = restTemplate.search(new NativeSearchQueryBuilder().withQuery(QueryBuilders.matchPhraseQuery("hobbies","烫头")).build(),Student.class);4.范围搜索Range 搜索SearchHits<Student> hits =restTemplate.search(new NativeSearchQueryBuilder().withQuery(QueryBuilders.rangeQuery("age").lte(35).gte(30)).build(),Student.class);5.Bool 搜索,多条件同时满足@Testvoid contextswLsoads() {BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();List<QueryBuilder> must = boolQueryBuilder.must();must.add(QueryBuilders.matchQuery("sname","zs"));must.add(QueryBuilders.rangeQuery("score").gt(0).lt(0.5));Query queryBuilder = new NativeSearchQueryBuilder().withQuery(boolQueryBuilder).build();SearchHits<Student> search = elasticsearchRestTemplate.search(queryBuilder, Student.class);}6.分页和排序* PageRequest类型中,提供静态方法of(int page, int size[, Sort sort]);* page - 查询第几页,页码数字从0开始计数。* size - 查询多少行。* Sort - 具体的排序规则。可选参数。SearchHits<Student> hits =restTemplate.search(new NativeSearchQueryBuilder().withQuery(QueryBuilders.matchAllQuery()).withPageable(PageRequest.of(0, 2,Sort.by(Sort.Order.desc("age"),Sort.Order.asc("id")))).build(),Student.class);7.高亮处理
@Test
public void testQueryHighLight(){// 创建高亮字段,必须和具体的字段名绑定。HighlightBuilder.Field field1 = new HighlightBuilder.Field("name");// 高亮前缀field1.preTags("<span style='color: red'>");// 高亮后缀field1.postTags("</span>");// 分段的每段字符数field1.fragmentSize(Integer.MAX_VALUE);// 分段后,返回几段field1.numOfFragments(1);Query query =new NativeSearchQueryBuilder().withQuery(QueryBuilders.matchQuery("name","于谦")).withHighlightFields(field1).build();SearchHits<Student> hits =restTemplate.search(query, Student.class);for (SearchHit<Student> hit : hits){// 获取源数据Student content = hit.getContent();// 找高亮数据List<String> hl = hit.getHighlightField("name");// 判断是否有高亮数据if(hl != null && hl.size() > 0){// 有高亮数据content.setName(hl.get(0));}System.out.println(content);}}