Spring Data Elasticsearch プロジェクト環境構築
1.1 pom ファイルを変更して依存関係を追加する
現在、spring-boot-starter-parent バージョン 2.6.8 を使用しています
対応する spring-data-elasticsearch のバージョンは 4.3.4 です
<!-- springDateElasticsearch依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
1.2 application.yml 構成ファイルを変更する
spring:
elasticsearch:
rest:
uris: http://192.168.8.128:9200
ElasticsearchTemplate の 2 つの使用法
2.1 エンティティ クラスの作成
@Document は、エンティティ クラスとインデックスの対応を指定します。
indexName: インデックス名
type: インデックス型 (ES 7.0 以降廃止)
shards: プライマリ シャードの数。ES 7 以降のデフォルトは 1
replicas: レプリケートされたシャードの数。ES 7 以降のデフォルトは 1
@Id は主キーを指定します
@Field は共通の属性を指定します
type: Elasticsearch の属性タイプに対応します。すばやくアクセスするには、FiledType 列挙型を使用します。
テキストタイプは分割可能
キーワードは単語分割できません
index: インデックスを作成するかどうか。検索条件として使用する場合、index は true でなければなりません
アナライザー: トークナイザーの種類を指定します。
@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查询文档
*/
@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查询文档
*/
@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);
}