<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
也可以在创建工程的时候选择依赖:
版本控制
演示代码使用的是7.8.1这个版本
<properties>
<java.version>1.8</java.version>
<elasticsearch.version>7.8.1</elasticsearch.version>
</properties>
如果以上方法无法生效,那可能需要按下面的代码来修改了:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
<exclusions>
<exclusion>
<artifactId>transport</artifactId>
<groupId>org.elasticsearch.client</groupId>
</exclusion>
</exclusions>
</dependency>
<!--引入es的RestHighLevelClient依赖:-->
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.8.1</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-client</artifactId>
<version>7.8.1</version>
</dependency>
package com.shenmazong.demoestemplate.pojo;
import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
/**
* @author 军哥
* @version 1.0
* @description: TODO
* @date 2021/7/4 13:34
*/
@Data
@Document(indexName = "tb_poem")
public class TbPoem {
@Id
private Long id;
@Field(type = FieldType.Text, analyzer = "ik_smart")
private String name;
@Field(type = FieldType.Keyword)
private String dynasty;
@Field(type = FieldType.Keyword)
private String author;
@Field(type = FieldType.Text, analyzer = "ik_smart")
private String content;
}
@SpringBootTest
class DemoEsTemplateApplicationTests {
@Autowired
private ElasticsearchRestTemplate elasticsearchRestTemplate;
@Test
void testCreate() {
if(!elasticsearchRestTemplate.indexOps(TbPoem.class).exists()) {
elasticsearchRestTemplate.indexOps(TbPoem.class).create();
System.out.println("create success");
return;
}
System.out.println("exist....");
return;
}
}
注意:创建索引时,也许是ElasticsearchRestTemplate的一个bug,无法把映射同时创建,后期有待调试,通过一下代码来自定义映射:
@Test
public void testCreate() {
//-- 删除
if(elasticsearchRestTemplate.indexOps(TbPoem.class).exists()) {
elasticsearchRestTemplate.indexOps(TbPoem.class).delete();
}
//-- 新建
elasticsearchRestTemplate.indexOps(TbPoem.class).create();
//-- 设置mapping
Document mapping = elasticsearchRestTemplate.indexOps(TbPoem.class).createMapping();
System.out.println(mapping);
elasticsearchRestTemplate.indexOps(TbPoem.class).putMapping(mapping);
}
@Test
void testDelete() {
if(!elasticsearchRestTemplate.indexOps(TbPoem.class).exists()) {
elasticsearchRestTemplate.indexOps(TbPoem.class).delete();
System.out.println("delete success");
return;
}
System.out.println("not exist....");
return;
}
@Test
void testAdd() {
TbPoem tbPoem = new TbPoem();
tbPoem.setId(1L);
tbPoem.setName("听雨");
tbPoem.setAuthor("蒋捷");
tbPoem.setDynasty("唐朝");
tbPoem.setContent("少年听雨阁楼上,红烛昏罗帐。");
elasticsearchRestTemplate.save(tbPoem);
}
@Test
void testBulkAdd() {
ArrayList<TbPoem> tbPoems = new ArrayList<>();
// 添加多个对象
// ... 略
elasticsearchRestTemplate.save(tbPoems);
}
@Test
void testGetDoc() {
TbPoem tbPoem = elasticsearchRestTemplate.get("1", TbPoem.class);
System.out.println(tbPoem);
}
@Test
void updateDoc() {
TbPoem tbPoem = elasticsearchRestTemplate.get("1", TbPoem.class);
tbPoem.setContent("少年听雨阁楼上,红烛昏罗帐。中年听雨客舟,");
elasticsearchRestTemplate.save(tbPoem);
}
@Test
void testDeleteDoc() {
TbPoem tbPoem = new TbPoem();
tbPoem.setId(1L);
//-- 方法1
elasticsearchRestTemplate.delete(tbPoem);
//-- 方法2
elasticsearchRestTemplate.get("1", TbPoem.class);
}
//不分词查询 参数1: 字段名,参数2:字段查询值,因为不分词,所以汉字只能查询一个字,英语是一个单词.
QueryBuilder queryBuilder=QueryBuilders.termQuery("fieldName", "fieldlValue");
QueryBuilder queryBuilder2 = QueryBuilders.matchQuery("fieldName", "fieldlValue");
//不分词查询,参数1: 字段名,参数2:多个字段查询值,因为不分词,所以汉字只能查询一个字,英语是一个单词.
QueryBuilder queryBuilder=QueryBuilders.termsQuery("fieldName", "fieldlValue1","fieldlValue2...");
QueryBuilder queryBuilder= QueryBuilders.multiMatchQuery("fieldlValue", "fieldName1", "fieldName2", "fieldName3");
QueryBuilder queryBuilder=QueryBuilders.matchAllQuery();
@PostMapping(value = "/term")
public ResultResponse term(
@RequestParam("keyWord") String keyWord,
@RequestParam("pageNum") Integer pageNum,
@RequestParam("pageSize") Integer pageSize
) {
//--1 构造分页
if(pageNum > 0) {
pageNum = pageNum -1;
}
PageRequest pageRequest = PageRequest.of(pageNum, pageSize);
//--2 builder
NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder();
//--3 构造查询
NativeSearchQuery query = builder.withPageable(pageRequest)
.withQuery(QueryBuilders.termQuery("name", keyWord))
.build();
//--4 执行查询
long count = elasticsearchRestTemplate.count(query, TbHero.class);
SearchHits<TbHero> searchHits = elasticsearchRestTemplate.search(query, TbHero.class);
//--5 获取查询的结果
List<SearchHit<TbHero>> hitsSearchHits = searchHits.getSearchHits();
hitsSearchHits.forEach(item -> {
TbHero tbHero = item.getContent();
System.out.println(tbHero);
});
//--6 手动分页
ArrayList<TbHero> tbHeroes = new ArrayList<>();
hitsSearchHits.forEach(item -> {
TbHero tbHero = item.getContent();
tbHeroes.add(tbHero);
});
HashMap<String, Object> map = new HashMap<>();
map.put("records", tbHeroes);
map.put("pageNum", pageNum+1);
map.put("pageSize", pageSize);
map.put("count", count);
return ResultResponse.SUCCESS(map);
}
查询关键字之间是或
的关系
@Test
void testTermsQuery() {
Pageable pageable = PageRequest.of(0, 10);
NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder();
NativeSearchQuery searchQuery = builder.withPageable(pageable)
.withQuery(QueryBuilders.termsQuery("content", "宫女", "日月"))
.build();
SearchHits<TbPoem> search = elasticsearchRestTemplate.search(searchQuery, TbPoem.class);
List<SearchHit<TbPoem>> searchHits = search.getSearchHits();
for (SearchHit<TbPoem> searchHit : searchHits) {
TbPoem tbPoem = searchHit.getContent();
System.out.println(tbPoem);
}
}
@Test
void testMatchQuery() {
Pageable pageable = PageRequest.of(0, 10);
NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder();
NativeSearchQuery searchQuery = builder.withPageable(pageable)
.withQuery(QueryBuilders.matchQuery("content", "宫 女"))
.build();
SearchHits<TbPoem> search = elasticsearchRestTemplate.search(searchQuery, TbPoem.class);
List<SearchHit<TbPoem>> searchHits = search.getSearchHits();
for (SearchHit<TbPoem> searchHit : searchHits) {
TbPoem tbPoem = searchHit.getContent();
System.out.println(tbPoem);
}
}
@Test
void testMultiMatchQuery() {
Pageable pageable = PageRequest.of(0, 10);
NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder();
NativeSearchQuery searchQuery = builder.withPageable(pageable)
.withQuery(QueryBuilders.multiMatchQuery("宫 女", "content", "name"))
.build();
SearchHits<TbPoem> search = elasticsearchRestTemplate.search(searchQuery, TbPoem.class);
List<SearchHit<TbPoem>> searchHits = search.getSearchHits();
for (SearchHit<TbPoem> searchHit : searchHits) {
TbPoem tbPoem = searchHit.getContent();
System.out.println(tbPoem);
}
}
@Test
void testMultiMatchQuery() {
Pageable pageable = PageRequest.of(0, 10);
NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder();
// 使用排序
SortBuilder order = new FieldSortBuilder("author").order(SortOrder.DESC);
NativeSearchQuery searchQuery = builder.withPageable(pageable)
.withQuery(QueryBuilders.multiMatchQuery("宫 女", "content", "name"))
.withSort(order)
.build();
SearchHits<TbPoem> search = elasticsearchRestTemplate.search(searchQuery, TbPoem.class);
List<SearchHit<TbPoem>> searchHits = search.getSearchHits();
for (SearchHit<TbPoem> searchHit : searchHits) {
TbPoem tbPoem = searchHit.getContent();
System.out.println(tbPoem);
}
}
@PostMapping(value = "/highlight")
public ResultResponse highlight(
@RequestParam("keyWord") String keyWord,
@RequestParam("pageNum") Integer pageNum,
@RequestParam("pageSize") Integer pageSize
) {
//--1 构造分页
if(pageNum > 0) {
pageNum = pageNum -1;
}
PageRequest pageRequest = PageRequest.of(pageNum, pageSize);
//--2 builder
NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder();
HighlightBuilder highlightBuilder = new HighlightBuilder();
highlightBuilder.preTags("<font color='red>").postTags("</font>").field("name");
//--3 构造查询
NativeSearchQuery query = builder.withPageable(pageRequest)
.withQuery(QueryBuilders.matchQuery("name", keyWord))
.withHighlightBuilder(highlightBuilder)
.build();
//--4 执行查询
long count = elasticsearchRestTemplate.count(query, TbHero.class);
SearchHits<TbHero> searchHits = elasticsearchRestTemplate.search(query, TbHero.class);
//--5 获取查询的结果
List<SearchHit<TbHero>> hitsSearchHits = searchHits.getSearchHits();
hitsSearchHits.forEach(item -> {
TbHero tbHero = item.getContent();
System.out.println(tbHero);
});
//--6 手动分页
ArrayList<TbHero> tbHeroes = new ArrayList<>();
hitsSearchHits.forEach(item -> {
TbHero tbHero = item.getContent();
List<String> names = item.getHighlightField("name");
if(names != null && names.size()>0) {
String s = names.get(0);
tbHero.setName(s);
}
tbHeroes.add(tbHero);
});
HashMap<String, Object> map = new HashMap<>();
map.put("records", tbHeroes);
map.put("pageNum", pageNum+1);
map.put("pageSize", pageSize);
map.put("count", count);
return ResultResponse.SUCCESS(map);
}
/**
* 用在类上作用:将Emp的对象映射成ES中一条json格式文档
* indexName: 用来指定这个对象的转为json文档存入那个索引中 要求:ES服务器中之前不能存在此索引名
* type : 用来指定在当前这个索引下创建的类型名称
*
* @Author Christy
* @Date 2021/4/29 21:22
*/
@Data
@Document(indexName = "christy",type = "user")
public class User {
@Id //用来将对象中id属性与文档中_id 一一对应
private String id;
// 用在属性上 代表mapping中一个属性 一个字段 type:属性 用来指定字段类型 analyzer:指定分词器
@Field(type = FieldType.Text,analyzer = "ik_max_word")
private String name;
@Field(type = FieldType.Integer)
private Integer age;
@Field(type = FieldType.Date)
@JsonFormat(pattern = "yyyy-MM-dd")
private Date bir;
@Field(type = FieldType.Text,analyzer = "ik_max_word")
private String content;
@Field(type = FieldType.Text,analyzer = "ik_max_word")
private String address;
}
package com.shenmazong.pojo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.DateFormat;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
/**
* 小说表
* @TableName tb_story
*/
@TableName(value ="tb_story")
@Data
@Document(indexName = "tb_story", shards = 1, replicas = 1)
public class TbStory implements Serializable {
/**
* 小说ID
*/
@TableId(type = IdType.AUTO)
@Id
private Integer id;
/**
* 小说名字
*/
@Field(type = FieldType.Text, analyzer = "ik_smart")
private String name;
/**
* 小说作者
*/
@Field(type = FieldType.Keyword)
private String author;
/**
* 小说内容
*/
@Field(type = FieldType.Text, analyzer = "ik_max_word")
private String content;
/**
* 点赞状态:0支持1反对
*/
@Field(type = FieldType.Integer)
private Integer status;
/**
* 软删除:0正常1删除
*/
@Field(type = FieldType.Integer)
private Integer deleted;
/**
* 创建时间
*/
@Field(type = FieldType.Date, format = DateFormat.custom, pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
private Date createTime;
/**
* 修改时间
*/
@Field(type = FieldType.Date, format = DateFormat.custom, pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
private Date updateTime;
@TableField(exist = false)
private static final long serialVersionUID = 1L;
}
参考网址: