目录
一、简介
二、配置
三、映射
四、 常用方法
五、操作(重点)
1、对索引表的操作
2、对文档的操作(重点)
(1)、添加文档
(2)、删除文档
(3)、查询文档(重点)
查询全部文档 (两种方式)
matchQuery根据关键字拆分进行全局搜索
matchPhraseQuery短语搜索--完整搜索
rangeQuery范围搜索
termQuery精确搜索
boolQuery()复合查询
withPageable分页查询
withSorts对结果进行排序
高亮查询
springData 操作ES类似于Mybatis-plus操作Mysql,都是简单易用
本博客基于springboot2最新方式操作 Elasticsearch7.12.1
采用gradle构建 (maven构建一直失败)
implementation 'org.springframework.boot:spring-boot-starter-data-elasticsearch'
最新的yml配置
spring:
elasticsearch:
uris: http://ip:9200
映射pojo
@Data
@NoArgsConstructor
@AllArgsConstructor
@Document(indexName ="people_index") // 索引名字
public class People {
@Id
private String id;
// Keyword类型不被分词索引 类型 分词器
@Field(type = FieldType.Text,analyzer = "ik_max_word")
private String name;
@Field(type = FieldType.Text,analyzer = "ik_max_word")
private String address;
// index = false 不建立分词索引
@Field(type = FieldType.Long,index = true)
private int age;
}
根据pojo创建索引
@SpringBootTestclass
EsDemo1ApplicationTests {
// 直接注入使用
@Autowired
ElasticsearchRestTemplate elasticsearchTemplate;
@Test
void esTest(){
// 创建索引
IndexOperations indexOperations = elasticsearchTemplate.indexOps(People.class);
if(!indexOperations.exists()) { // 当前索引不存在
boolean result1 =indexOperations.create();// 只是创建索引 。mappings没有映射
boolean result2 = indexOperations.putMapping();// 映射属性
System.out.println("创建结果:" + ",映射结果:" + result2);
}else {
System.out.println("文档已存在");
}
}
验证索引表是否创建成功
GET people_index/_mapping
ElasticsearchRestTemplate 常用方法
1、save :保存或者更新文档
elasticsearchRestTemplate.save(object);
2、index: 保存或更新文档数据到指定索引和类型中
IndexQuery indexQuery = new IndexQueryBuilder().withObject(object).build();
elasticsearchRestTemplate.index(indexQuery, IndexCoordinates.of(indexName));
3、get: 根据文档 ID 获取文档数据。
elasticsearchRestTemplate.get(id, DocumentClass.class);
4、update: 更新指定文档的数据。
UpdateQuery updateQuery = new UpdateQueryBuilder().withId(id).withObject(updatedObject).build();
elasticsearchRestTemplate.update(updateQuery, IndexCoordinates.of(indexName));
5、delete: 删除指定文档。
elasticsearchRestTemplate.delete(id, IndexCoordinates.of(indexName));
6、exists: 判断指定文档是否存在。
elasticsearchRestTemplate.exists(id, IndexCoordinates.of(indexName));
7、search: 执行搜索操作,使用 Query 条件进行搜索。
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
.withQuery(QueryBuilders.matchQuery("field", "value"))
.build();
List resultList = elasticsearchRestTemplate.search(searchQuery, DocumentClass.class, IndexCoordinates.of(indexName));
8、count: 计算满足指定条件的文档数量。
NativeSearchQuery countQuery = new NativeSearchQueryBuilder()
.withQuery(QueryBuilders.matchQuery("field", "value"))
.build();
long count = elasticsearchRestTemplate.count(countQuery, IndexCoordinates.of(indexName));
IndexOperations 常用方法
1、create():创建索引。如果索引已存在,则会抛出异常。
2、delete():删除索引。如果索引不存在,则会抛出异常。
3、exists():检查索引是否存在。
4、putMapping():为索引设置映射。MappingContext 是 Spring Data Elasticsearch 提供的用于获取实体类映射信息的接口。
5、refresh():刷新索引,使之可搜索最新添加的文档。在索引文档后,需要调用 refresh() 方法才能保证文档可以被搜索到。
6、getIndexSettings():获取索引的配置信息。
7、getAliases():获取索引的别名信息。
8、addAlias(AliasQuery aliasQuery):添加别名。
9、removeAlias(AliasQuery aliasQuery):移除别名。
10、getSettings():获取索引的详细配置信息。
11、updateSettings(UpdateSettingsRequest request):更新索引的配置信息。
其实真正常用的也就是
保存/修改文档
elasticsearchRestTemplate.save()
查询文档
elasticsearchRestTemplate.search()
以及NativeSearchQuery 搜索对象
对索引表的操作常用的也就是,创建/修改、删除
创建就是上面提到的映射
删除索引表:
@Test
void esTest2(){
IndexOperations indexOperations = elasticsearchTemplate.indexOps(People.class);
boolean delete = indexOperations.delete(); // 删除索引
System.out.println("删除索引:"+delete);
}
对于ES来说,索引就是表,文档就是数据
添加一条
// 添加文档
@Test
void esTest3(){
People people=new People();
people.setId("1232");
people.setName("张三");
people.setAge(32);
// 保存文档--save 根据文档id修改或者创建文档
People save = elasticsearchTemplate.save(people);
}
批量添加
// 批量添加
@Test
void esTest4(){
List list= Arrays.asList(new People("1","李四","长沙",23),
new People("2","李四","长沙",23),
new People("3","李四","长沙",23),
new People("4","李四","长沙",23)
);
Iterable save1 = elasticsearchTemplate.save(list);
System.out.println("数据"+save1);
}
检查是否添加完成
GET people_index/_search
// 删除操作
@Test
void esTest5(){
// id // 对应索引库
String delete = elasticsearchTemplate.delete("1", People.class);
}
除了根据id删除文档外,还可以根据条件删除文档,请类比下面的查询操作
matchQuery按关键字查询(关键字也会被拆分),示例
@Test
void query(){
// 创建查询 字段--索引
NativeSearchQuery searchQuery=new NativeSearchQueryBuilder().withQuery(QueryBuilders.matchQuery("address", "太阳")).build(); //
// 查询
SearchHits search1 = elasticsearchTemplate.search(searchQuery, People.class);
search1.forEach(System.out::println);
}
// 第一种 ,不加查询条件
@Test
void query(){
// 查询--全部文档
SearchHits search1 = elasticsearchTemplate.search(new NativeSearchQueryBuilder().build(), People.class);
search1.forEach(System.out::println);
}
// 第二种
// 查询全部
//matchAllQuery
@Test
void query3(){
// 创建查询 字段--索引
NativeSearchQuery searchQuery=new NativeSearchQueryBuilder()
// 根据关键字进行全局模糊搜索
.withQuery(QueryBuilders.matchAllQuery())
.build();
// 查询
SearchHits search1 = elasticsearchTemplate.search(searchQuery,People.class);
search1.forEach(System.out::println);}
@Test
void query1(){
// 创建查询 字段--索引
NativeSearchQuery searchQuery=new NativeSearchQueryBuilder()
// 根据关键字进行全局模糊搜索
.withQuery(QueryBuilders.matchQuery("李四")) // "李四"会被拆分成关键字进行搜索
.build();
// 查询
SearchHits search1 = elasticsearchTemplate.search(searchQuery,People.class);
search1.forEach(System.out::println);
}
不会对关键字的拆分搜索
// 短语搜索
@Test
void query4(){
// 创建查询 字段--索引
NativeSearchQuery searchQuery=new NativeSearchQueryBuilder()
// 根据关键字进行全局模糊搜索
.withQuery(QueryBuilders.matchPhraseQuery("address","长沙市")) // “长沙市” 不会进行拆分
.build();
// 查询
SearchHits search1 = elasticsearchTemplate.search(searchQuery,People.class);
search1.forEach(System.out::println);
}
// 解释下什么是短语搜索
比如查询 "小明爱吃葡萄"
普通关键字查找(matchQuery),这句查找关键字会被拆分成 "小明","爱吃","葡萄" 等,查出的结果满足一个关键字即可,即查出来的结果可能会出现 "小明爱吃香蕉"
短语搜索出来的结果 就是以"小明爱吃葡萄"为关键字去搜索,不会对关键字再进行拆分
适用于数值类型
// 范围搜索
@Test
void query5(){
// 创建查询 字段--索引
NativeSearchQuery searchQuery=new NativeSearchQueryBuilder()
// 根据关键字进行全局模糊搜索 lte <= gte >=
.withQuery(QueryBuilders.rangeQuery("age").gte(10).lte(20))
.build();
// 查询
SearchHits search1 = elasticsearchTemplate.search(searchQuery,People.class);
search1.forEach(System.out::println);
}
注意: 对于text类型且使用的ik分词的字段而言, termQuery的作用和matchPhraseQuery 类似,所以termQuery 适用于keyword类型的字段和数值类型的字段
// 精确搜索
@Test
void query6(){
// 创建查询 字段--索引
NativeSearchQuery searchQuery=new NativeSearchQueryBuilder()
// 根据关键字进行全局模糊搜索 lte <= gte >=
.withQuery(QueryBuilders.termQuery("age",15))
.build();
// 查询
SearchHits search1 = elasticsearchTemplate.search(searchQuery,People.class);
search1.forEach(System.out::println);
}
对于优先级别问题 使用多个must 来处理
// 复合查询
@Test
void query7(){
// 创建查询 字段--索引
NativeSearchQuery searchQuery=new NativeSearchQueryBuilder()
// boolQuery 符合查询,must必须 should 或者
// name=李四 ||age>=30
// QueryBuilders.boolQuery().should(QueryBuilders.termQuery("name","李四")).should(QueryBuilders.rangeQuery("age").gte(30))
// name=李四 && age>=30
// QueryBuilders.boolQuery().must(QueryBuilders.termQuery("name","李四")).must(QueryBuilders.rangeQuery("age").gte(30))
// (name=李四 || age>=25) && age <=30 使用must 处理优先级问题
.withQuery(QueryBuilders.boolQuery()
.must(QueryBuilders.boolQuery().should(QueryBuilders.termQuery("name","李四")).should(QueryBuilders.rangeQuery("age").gte(25)))
.must(QueryBuilders.rangeQuery("age").lte(30)))
.build();
// 查询
SearchHits search1 = elasticsearchTemplate.search(searchQuery,People.class);
search1.forEach(System.out::println);
}
需要对查询结果进行封装
@Test
void query8() throws JsonProcessingException {
// 创建查询 字段--索引
NativeSearchQuery searchQuery=new NativeSearchQueryBuilder()
// 页码(从0开始) 每页条数
.withPageable(PageRequest.of(0,2))
.build();
// 查询
SearchHits search = elasticsearchTemplate.search(searchQuery, People.class);
// 对查询结果进行封装--Page
SearchPage searchHits = SearchHitSupport.searchPageFor(search, searchQuery.getPageable());
System.out.println("当前页码(从0开始):getNumber:"+searchHits.getNumber());
System.out.println("总页数:getTotalPages :"+searchHits.getTotalPages());
System.out.println("每页的最大数据条数:getSize: "+searchHits.getSize());
System.out.println("是否有下一页数据:hasNext: "+searchHits.hasNext());
System.out.println("是否有上一页数据:hasPrevious: "+searchHits.hasPrevious());
System.out.println("当前页数据:getContent: "+searchHits.getContent());
String s = objectMapper.writeValueAsString(searchHits);
System.out.println("json:"+s);
}
@Test
void query8() throws JsonProcessingException {
// 创建查询 字段--索引
NativeSearchQuery searchQuery=new NativeSearchQueryBuilder()
// 查询全部
.withQuery(QueryBuilders.matchAllQuery())
// 根据 age 字段进行从大到小排序
// 字段 排序规则
.withSorts(SortBuilders.fieldSort("age").order(SortOrder.DESC))
.build();
// 查询
SearchHits search = elasticsearchTemplate.search(searchQuery, People.class);
search.forEach(System.out::println);
}
把查询结果的关键字进行高亮处理
// 高亮查询
@Test
void query9() throws JsonProcessingException {
// 创建查询 字段--索引
// 创建高亮设置
HighlightBuilder highlightBuilder=new HighlightBuilder();
// 设置高亮的结果字段 结果前面添加内容 后续添加内容
highlightBuilder.field("address").preTags("").postTags("");
highlightBuilder.field("name").preTags("").postTags("");
NativeSearchQuery searchQuery=new NativeSearchQueryBuilder()
.withQuery(QueryBuilders.matchQuery("address","长沙"))
// 处理高亮
.withHighlightBuilder(highlightBuilder)
.build();
// 查询
SearchHits search = elasticsearchTemplate.search(searchQuery, People.class);
// 查询结果为SearchHits --SearchHit为封装的单个数据,高亮数据在highlightFields 中
List> searchHits = search.getSearchHits();
searchHits.forEach(System.out::println);
}