使用Spring Data Elasticsearch 进行索引的增、删、改、查
一 Spring Data Elasticsearch 项目环境搭建
1.1 修改pom文件添加依赖
目前使用spring-boot-starter-parent版本为2.2.8.RELEASE
对应spring-data-elasticsearch版本为2.2.8.RELEASE,版本对应可以自行百度,如果不行直接用elasticsearch-rest-high-level-client工具类吧
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
<version>2.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>7.5.0</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-client</artifactId>
<version>7.5.0</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.5.0</version>
</dependency>
1.2 新建配置文件
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* ES配置类
*
* @author lc
* @version 1.0
* @date 2022/3/25 10:53
*/
@Configuration
public class ElasticSearchClientConfig {
@Bean
public RestHighLevelClient restHighLevelClient() {
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(new HttpHost("192.168.1.100", 9200, "http")));
return client;
}
}
二 ElasticsearchTemplate的使用
2.1 创建实体类
@Document指定实体类和索引对应关系
indexName:索引名称
type: 索引类型(从ES 7.0 开始已经过时了)
shards: 主分片数量。从ES 7开始默认1
replicas:复制分片数量。从ES 7开始默认1
@Id 指定主键
@Field指定普通属性
type: 对应Elasticsearch中属性类型。使用FiledType枚举可以快速获取。
text类型能被分词
keywords不能被分词
index: 是否创建索引。作为搜索条件时index必须为true
analyzer:指定分词器类型。
@Data
@Document(indexName = "student_index",shards = 1,replicas = 1)
public class Student {
@Id
private String id;
@Field(type = FieldType.Keyword)
private String name;
@Field(type = FieldType.Text,analyzer = "ik_max_word")
private String desc;
@Field(type = FieldType.Text,analyzer = "ik_max_word")
private String data;
@Field(type = FieldType.Integer)
private Integer age;
}
2.2 初始化索引
@Autowired
private ElasticsearchRestTemplate elasticsearchRestTemplate;
@Test
void createIndex() {
// 从 spring data es 4.0开始所有索引操作都在这个接口
IndexOperations indexOperations = elasticsearchRestTemplate.indexOps(Student.class);
// 是否存在,存在则删除
if(indexOperations.exists()){
indexOperations.delete();
}
// 创建索引
indexOperations.create();
// createMapping 根据实体类获取映射关系
// putMapping 把映射关系添加到索引中
Document mapping = indexOperations.createMapping(Student.class);
indexOperations.putMapping(mapping);
}
2.3 删除索引
/**
* 删除索引
*/
@Test
void deleteIndex() {
IndexOperations indexOperations = elasticsearchRestTemplate.indexOps(Student.class);
boolean delete = indexOperations.delete();
System.out.println(delete);
}
2.4 新增文档
- 新增单个文档
/**
* 新增单个文档
*/
@Test
void insert(){
Student student = new Student();
student.setAge(23);
student.setData("123");
student.setDesc("华为手机");
student.setId("1");
student.setName("张三");
Student save = elasticsearchRestTemplate.save(student);
System.out.println(save);
}
- 批量新增
/**
* 批量新增
*/
@Test
void batchInsert(){
List<Student> list = new ArrayList<>();
list.add(new Student("2","李四","苹果手机","1",22));
list.add(new Student("3","王五","oppo手机","2",24));
list.add(new Student("4","赵六","voio手机","3",25));
list.add(new Student("5","田七","小米手机","4",26));
Iterable<Student> result = elasticsearchRestTemplate.save(list);
System.out.println(result);
}
2.5 删除操作
- 根据主键删除
/**
* 根据主键删除
*/
@Test
void deleteById() {
// 根据id删除
String delete = elasticsearchRestTemplate.delete("5", Student.class);
System.out.println(delete);
}
- 根据条件删除
/**
* 根据查询条件删除
*/
@Test
void delete() {
QueryStringQueryBuilder queryBuilder = QueryBuilders.queryStringQuery("张三");
Query query = new NativeSearchQuery(queryBuilder);
ByQueryResponse QueryDelete = elasticsearchRestTemplate.delete(query, Student.class);
System.out.println(QueryDelete);
}
2.6 修改操作
- 全量替换
/**
* 批量修改
*/
@Test
void update(){
Student student = new Student();
student.setId("1");
student.setAge(23);
student.setData("99");
student.setDesc("华为手机AND苹果手机");
student.setName("张三");
Student save = elasticsearchRestTemplate.save(student);
System.out.println(save);
}
- 部分修改
/**
* 部分修改
*/
@Test
void update2(){
// ctx._source 固定写法
String script = "ctx._source.age = 27;ctx._source.desc = 'oppo手机and苹果电脑'";
UpdateQuery build = UpdateQuery.builder("3").withScript(script).build();
IndexCoordinates indexCoordinates = IndexCoordinates.of("student_index");
UpdateResponse update = elasticsearchRestTemplate.update(build, indexCoordinates);
System.out.println(update.getResult());
}
2.7 查询操作
- 根据主键查询
/**
* 根据主键查查询
*/
@Test
void searchById(){
Student student = elasticsearchRestTemplate.get("3", Student.class);
System.out.println(student);
}
- 模糊查询
/**
* 模糊查询
*/
@Test
void LikeSearch(){
QueryStringQueryBuilder queryBuilder = QueryBuilders.queryStringQuery("手机");
Query query = new NativeSearchQuery(queryBuilder);
SearchHits<Student> search = elasticsearchRestTemplate.search(query, Student.class);
List<SearchHit<Student>> searchHits = search.getSearchHits();
List<Student> list = new ArrayList<>();
searchHits.forEach(sh->{
list.add(sh.getContent());
});
System.out.println(list);
}
- 使用match_all查询所有文档
/**
* 使用match_all查询所有文档
*/
@Test
void matchAllSearch(){
MatchAllQueryBuilder queryBuilder = QueryBuilders.matchAllQuery();
Query query = new NativeSearchQuery(queryBuilder);
SearchHits<Student> search = elasticsearchRestTemplate.search(query, Student.class);
List<SearchHit<Student>> searchHits = search.getSearchHits();
List<Student> list = new ArrayList<>();
searchHits.forEach(sh->{
list.add(sh.getContent());
});
System.out.println(list);
}
- 使用match查询文档
/**
* 使用match查询文档
*/
@Test
void matchSearch(){
Query query = new NativeSearchQuery( QueryBuilders.matchQuery("name","张三"));
SearchHits<Student> search = elasticsearchRestTemplate.search(query, Student.class);
List<SearchHit<Student>> searchHits = search.getSearchHits();
System.out.println(search.getTotalHits());
List<Student> list = new ArrayList<>();
searchHits.forEach(sh->{
list.add(sh.getContent());
});
System.out.println(list);
}
- 使用match_phrase查询文档
/**
* 使用match_phrase查询文档
* 短语搜索是对条件不分词,但是文档中属性根据配置实体类时指定的分词类型进行分词。
* 如果属性使用ik分词器,从分词后的索引数据中进行匹配。
*/
@Test
void matchPhraseSearch(){
Query query = new NativeSearchQuery( QueryBuilders.matchPhraseQuery("desc","电脑"));
SearchHits<Student> search = elasticsearchRestTemplate.search(query, Student.class);
List<SearchHit<Student>> searchHits = search.getSearchHits();
System.out.println(search.getTotalHits());
List<Student> list = new ArrayList<>();
searchHits.forEach(sh->{
list.add(sh.getContent());
});
System.out.println(list);
}
- 使用range查询文档
/**
* 使用range查询文档
*/
@Test
void rangeSearch(){
Query query = new NativeSearchQuery( QueryBuilders.rangeQuery("age").gte("24").lte(29));
SearchHits<Student> search = elasticsearchRestTemplate.search(query, Student.class);
List<SearchHit<Student>> searchHits = search.getSearchHits();
System.out.println(search.getTotalHits());
List<Student> list = new ArrayList<>();
searchHits.forEach(sh->{
list.add(sh.getContent());
});
System.out.println(list);
}
- 多条件查询
/**
* 多条件查询
*/
@Test
void querysSearch(){
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
List<QueryBuilder> listQuery = new ArrayList<>();
listQuery.add(QueryBuilders.matchQuery("name","张三"));
listQuery.add(QueryBuilders.matchQuery("age","23"));
boolQueryBuilder.must().addAll(listQuery);// 逻辑 与
// boolQueryBuilder.should().addAll(listQuery);// 逻辑 或
BoolQueryBuilder boolQueryBuilder2 = QueryBuilders.boolQuery();
List<QueryBuilder> listQuery2 = new ArrayList<>();
listQuery2.add(QueryBuilders.matchQuery("name","李四"));
listQuery2.add(QueryBuilders.matchQuery("age","22"));
boolQueryBuilder2.must().addAll(listQuery2);// 逻辑 与
BoolQueryBuilder boolQueryBuilder3 = QueryBuilders.boolQuery();
List<QueryBuilder> listQuery3 = new ArrayList<>();
listQuery3.add(boolQueryBuilder);
listQuery3.add(boolQueryBuilder2);
boolQueryBuilder3.should().addAll(listQuery3);// 逻辑 或
boolQueryBuilder3.must().addAll(listQuery3);// 逻辑 与
NativeSearchQuery nativeSearchQuery = new NativeSearchQuery(boolQueryBuilder3);
SearchHits<Student> search = elasticsearchRestTemplate.search(nativeSearchQuery, Student.class);
List<SearchHit<Student>> searchHits = search.getSearchHits();
System.out.println(search.getTotalHits());
List<Student> list = new ArrayList<>();
searchHits.forEach(sh->{
list.add(sh.getContent());
});
System.out.println(list);
}
- 分页与排序
/**
* 分页查询
*/
@Test
void pageSearch(){
Query query = new NativeSearchQuery(QueryBuilders.matchAllQuery());
// 排序
query.addSort(Sort.by(Sort.Direction.DESC,"age"));
// 分页
query.setPageable(PageRequest.of(1,2));
SearchHits<Student> searchHits = elasticsearchRestTemplate.search(query, Student.class);
System.out.println(searchHits.getTotalHits());
List<SearchHit<Student>> hitList = searchHits.getSearchHits();
List<Student> listResult = new ArrayList<>();
hitList.forEach(list->{
listResult.add(list.getContent());
});
System.out.println(listResult);
}