一、环境搭建
(1)导入依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.12.RELEASE</version>
</parent><dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
(2)编辑配置文件
# 注意: 地址一定不要有末尾字符 '/'
# ElasticsearchRestTemplate客户端的配置
spring:
elasticsearch:
rest:
uris: http://192.168.8.128:9200 # ES服务器所在位置。集群多节点地址用逗号分隔。默认http://localhost:9200
# data: # ElasticsearchTemplate客户端配置。所有的方法API和ElasticsearchRestTemplate完全相同。
# elasticsearch:
# cluster-name: docker-cluster # ES集群的名称。已过期
# cluster-nodes: 192.168.137.128:9300 # ES集群多节点地址。多个地址用逗号分隔。在7版本后已过期
(3)编辑实体类型
-
/**
-
* Document - 描述类型和索引的映射。
-
* indexName - 索引名称
-
* shards - 主分片数量。默认值 1。
-
* replicas - 副本分片数量。默认值 1。
-
*/
-
@Data
-
@NoArgsConstructor
-
@AllArgsConstructor
-
@Document(indexName = "stu_index", shards = 1, replicas = 0)
-
public
class
Student
implements
Serializable {
-
/**
-
* Field - 当前属性和索引中的字段映射规则。
-
* name - 字段名称。默认和当前类型属性名一致。
-
* type - 字段类型。默认使用FieldType.AUTO。自动识别。
-
* analyzer - 分词器。所有的Text类型字段默认使用standard分词器。
-
* index - 是否创建索引。默认值 true。
-
* format - 如果字段类型是date日期类型。此属性必须配置,用于设置日期格式化规则,使用DateFormat类型中的常量定义。
-
*/
-
@Id
-
@Field(name = "id", type = FieldType.Keyword)
-
private Long id;
-
@Field(name = "name", type = FieldType.Text, analyzer = "ik_max_word")
-
private String name;
-
@Field(name = "gender", type = FieldType.Keyword)
-
private String gender;
-
@Field(name = "age", type = FieldType.Integer)
-
private
int age;
-
@Field(name = "hobbies", type = FieldType.Text, analyzer = "ik_smart")
-
private List<String> hobbies;
-
@Field(name = "isMarried", type = FieldType.Boolean)
-
private
boolean isMarried;
-
@Field(name = "books", type = FieldType.Text, analyzer = "ik_smart", index = false)
-
private String[] books;
-
@Field(name = "birth", type = FieldType.Date, format = DateFormat.basic_date_time)
-
private Date birth;
-
}
二、使用
(1)创建索引
-
@SpringBootTest
-
public
class
TestDataES {
-
/**
-
* Spring Data Elasticsearch客户端类型 - ElasticsearchRestTemplate客户端对象,
-
* 由spring-boot-starter-data-elasticsearch启动时,自动装配创建。
-
* 要求:
-
* 1. 当前应用中,必须有启动类型,才能自动装配创建。
-
* 2. 创建客户端时,根据配置文件,实现服务器连接。默认连接的ES服务器集群是:http://localhost:9200
-
*/
-
@Autowired
-
private ElasticsearchRestTemplate restTemplate;
-
-
/**
-
* 创建索引
-
*/
-
@Test
-
public
void
testCreateIndex
(){
-
/*
-
* 在spring data elasticsearch中,所有的索引相关操作都封装在一个操作对象 IndexOperations 中。
-
* 基于一个实体类型的类对象,创建索引操作对象。实体类型中,有使用注解描述的索引和映射相关信息。可以做为索引的创建的设置。
-
*/
-
IndexOperations
indexOps
= restTemplate.indexOps(Student.class);
-
-
// 创建索引
-
indexOps.create();
-
}
-
}
(2)设置映射
-
/**
-
* 设置映射
-
* 在商业开发中,几乎不会使用框架创建索引或设置映射。因为这是架构或者管理员的工作。且不适合使用代码实现
-
*/
-
@Test
-
public
void
testCreateIndexAndPutMapping
(){
-
IndexOperations
indexOps
= restTemplate.indexOps(Student.class);
-
-
// 设置映射
-
indexOps.putMapping(indexOps.createMapping());
-
}
(3)删除索引
-
/**
-
* 删除索引
-
*/
-
@Test
-
public
void
testDeleteIndex
(){
-
restTemplate.indexOps(Student.class).delete();
-
}
(4)新增单一文档
-
/**
-
* 新增单一文档
-
*/
-
@Test
-
public
void
testAddDocument
()
throws Exception{
-
// 创建要新增的实体对象。手工赋予主键,返回结果就是新增的数据对象。
-
Student
student
=
new
Student();
-
student.setId(
1L);
-
student.setName(
"张三");
-
student.setGender(
"男");
-
student.setAge(
25);
-
SimpleDateFormat
sdf
=
new
SimpleDateFormat(
"yyyy-MM-dd");
-
student.setBirth(sdf.parse(
"1996-01-01"));
-
student.setBooks(
new
String[]{
"Java面向对象思想",
"Spring In Action"});
-
student.setHobbies(Arrays.asList(
"吃饭",
"上班",
"睡觉"));
-
student.setMarried(
true);
-
-
// 保存数据到Elasticsearch
-
student = restTemplate.save(student);
-
-
System.out.println(student);
-
-
System.out.println(
"====================================================");
-
-
// 自动生成主键,返回的结果中包含Elasticsearch生成的主键。
-
student =
new
Student();
-
student.setName(
"李四");
-
student.setGender(
"男");
-
student.setAge(
21);
-
student.setBirth(sdf.parse(
"2000-01-01"));
-
student.setBooks(
new
String[]{
"火影忍者",
"海贼王"});
-
student.setHobbies(Arrays.asList(
"玩游戏",
"睡觉",
"看动漫"));
-
student.setMarried(
false);
-
-
student = restTemplate.save(student);
-
-
System.out.println(student);
-
}
(5)批量新增文档
-
/**
-
* 批量新增文档
-
*/
-
@Test
-
public
void
testBatchAdd
()
throws Exception {
-
SimpleDateFormat
sdf
=
new
SimpleDateFormat(
"yyyy-MM-dd");
-
-
List<Student> list =
new
ArrayList<>();
-
list.add(
new
Student(
2L,
"郭德纲",
"男",
48, Arrays.asList(
"郭麒麟"),
true,
new
String[]{
"德云逗笑社"}, sdf.parse(
"1973-01-18")));
-
list.add(
new
Student(
3L,
"于谦",
"男",
52, Arrays.asList(
"郭麒麟",
"抽烟",
"喝酒",
"烫头"),
true,
new
String[]{
"德云逗笑社"}, sdf.parse(
"1969-01-24")));
-
-
restTemplate.save(list);
-
-
System.out.println(
"批量新增结束");
-
}
(6)删除文档
-
/**
-
* 删除文档
-
*/
-
@Test
-
public
void
testDeleteDocument
(){
-
// 删除类型对应的索引中的指定主键数据,返回删除数据的主键。注意:Elasticsearch中的文档主键都是字符串类型的。
-
String
response
= restTemplate.delete(
"1", Student.class);
-
-
System.out.println(response);
-
}
(7)更新文档
-
/**
-
* 更新文档。
-
* 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());
-
}
三、查询
(1)主键查询文档
-
/**
-
* 主键查询文档
-
*/
-
@Test
-
public
void
testGetById
(){
-
Student
student
= restTemplate.get(
"3", Student.class);
-
System.out.println(student);
-
}
(2)全字段搜索
-
/**
-
* querystring 搜索。所有的搜索的套路一致。具体方法如下:
-
* SearchHits search(Query query, Class<T> clazz);
-
* 参数query - 具体的条件。是spring data elasticsearch框架封装的类型。
-
* 一般使用构建器创建搜索条件。
-
* NativeSearchQueryBuilder().build()
-
* .withQuery(QueryBuilder) - 提供具体的条件。此方法的参数类型是QueryBuilder
-
* 这个QueryBuilder类型由elasticsearch提供的java客户端jar包定义。
-
* QueryBuilder对象,一般使用构建器创建,QueryBuilders
-
* 参数clazz - 返回结果每个document封装的对象类型。
-
* 返回return - 搜索的结果。是一个完整的搜索结果对象。包含总数据个数,当前搜索集合,是否超时等。
-
*
-
* SearchHits类型实现了Iterable接口,可迭代。容器中每个对象的类型是SearchHit。
-
* SearchHit类型中包含一个完整的搜索对象,由元数据和源数据组成。
-
*/
-
@Test
-
public
void
testQuerystring
(){
-
QueryBuilder
queryBuilder
=
-
QueryBuilders.queryStringQuery(
"郭");
-
-
Query
query
=
-
new
NativeSearchQueryBuilder()
-
.withQuery(queryBuilder)
// 提供具体的条件。
-
.build();
-
-
SearchHits<Student> hits =
-
restTemplate.search(query, Student.class);
-
-
System.out.println(
"搜索结果数据个数是: " + hits.getTotalHits());
-
-
for(SearchHit<Student> hit : hits){
-
// 源数据,就是保存在Elasticsearch中的数据
-
Student
content
= hit.getContent();
-
System.out.println(
"源数据:" + content);
-
}
-
}
(3)搜索全部
-
/**
-
* 搜索全部
-
*/
-
@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());
-
}
-
}
(4)匹配搜索
-
/**
-
* match搜索
-
*/
-
@Test
-
public
void
testQueryByMatch
(){
-
SearchHits<Student> hits = restTemplate.search(
-
new
NativeSearchQueryBuilder()
-
.withQuery(
-
QueryBuilders.matchQuery(
-
"name",
-
"于谦")
-
)
-
.build(),
-
Student.class
-
);
-
-
print(hits);
-
-
}
-
-
private
void
print
(SearchHits<Student> hits){
-
for(SearchHit<Student> hit : hits){
-
System.out.println(hit.getContent());
-
}
-
}
(5)短语搜索
-
/**
-
* match phrase搜索
-
*/
-
@Test
-
public
void
testQueryByMatchPhrase
(){
-
SearchHits<Student> hits = restTemplate.search(
-
new
NativeSearchQueryBuilder()
-
.withQuery(
-
QueryBuilders.matchPhraseQuery(
-
"hobbies",
-
"烫头"
-
)
-
)
-
.build(),
-
Student.class
-
);
-
print(hits);
-
}
(6)范围搜索
-
/**
-
* range搜索
-
*/
-
@Test
-
public
void
testQueryByRange
(){
-
SearchHits<Student> hits =
-
restTemplate.search(
-
new
NativeSearchQueryBuilder()
-
.withQuery(
-
QueryBuilders.rangeQuery(
"age")
-
.lte(
35).gte(
30)
-
)
-
.build(),
-
Student.class
-
);
-
-
print(hits);
-
}
(7)范围搜索
-
/**
-
* bool搜索。多条件
-
*/
-
@Test
-
public
void
testQueryByBool
(){
-
/*
-
* bool搜索条件中包含3个条件集合。List<QueryBuilder>,分别命名为must(必须匹配的条件),mustNot(必须不匹配的条件),should(任意匹配的条件)。
-
* 每个条件集合管理方案都提供了两个方法API。以must举例如下:
-
* must() - 获取must必要条件集合,返回List<QueryBuilder>。
-
* must(QueryBuilder) - 把参数添加到must条件集合中,返回BoolQueryBuilder类型对象,即当前对象本身(this)。
-
*/
-
BoolQueryBuilder
queryBuilder
=
-
QueryBuilders.boolQuery();
-
List<QueryBuilder> must = queryBuilder.must();
-
must.add(QueryBuilders.matchQuery(
"name",
"郭"));
-
queryBuilder.should(QueryBuilders.rangeQuery(
"age").gt(
30))
-
.should(QueryBuilders.rangeQuery(
"age").lt(
60));
-
-
// 搜索
-
SearchHits<Student> hits =
-
restTemplate.search(
-
new
NativeSearchQueryBuilder()
-
.withQuery(queryBuilder)
-
.build(),
-
Student.class
-
);
-
-
print(hits);
-
}
(8)分页和排序
-
/**
-
* 分页+排序
-
* 在spring data系列框架中,分页和排序可以混合处理。使用通用定义spring data commons中的Page接口实现。应用接口的实现类型PageRequest处理。
-
* PageRequest类型中,提供静态方法of(int page, int size[, Sort sort]);
-
* page - 查询第几页,页码数字从0开始计数。
-
* size - 查询多少行。
-
* Sort - 具体的排序规则。可选参数。
-
*/
-
@Test
-
public
void
testQueryByPageAndSort
(){
-
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
-
);
-
print(hits);
-
}
(9)高亮处理
-
/**
-
* 搜索结果高亮处理
-
* 提供高亮字段,字段名,是否分段(每段几个字符,返回几段),前后缀。
-
* 创建Query对象,做搜索处理。
-
*/
-
@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){
-
// 有高亮数据
-
(hl.get(
0));
-
}
-
System.out.println(content);
-
}
-
-
}
转载:https://blog.csdn.net/weixin_53455615/article/details/128267588