点击上方“Java基基”,选择“设为星标”
做积极的人,而不是积极废人!
每天 14:00 更新文章,每天掉亿点点头发...
源码精品专栏
原创 | Java 2021 超神之路,很肝~
中文详细注释的开源项目
RPC 框架 Dubbo 源码解析
网络应用框架 Netty 源码解析
消息中间件 RocketMQ 源码解析
数据库中间件 Sharding-JDBC 和 MyCAT 源码解析
作业调度中间件 Elastic-Job 源码解析
分布式事务中间件 TCC-Transaction 源码解析
Eureka 和 Hystrix 源码解析
Java 并发源码
来源:blog.csdn.net/weixin_44102992/
article/details/108033164/
前言
集成环境准备
1.导入spring-data-elasticsearch依赖
2.elasticsearch配置文件
3.实体类准备
4.Elasticsearch Service准备
简单查询
分词高亮查询
该文章需要提前准备好Elasticsearch7.6以及ik分词器的环境,如果还没准备好的可以看看
“https://blog.csdn.net/weixin_44102992/article/details/107954129
“推荐下自己做的 Spring Boot 的实战项目:
https://github.com/YunaiV/ruoyi-vue-pro
版本需要与Elasticsearch一致,还需要注意自己的springboot版本是否支持
“本文springboot为2.3,依赖也为2.3,elasticsearch为7.6.2
org.springframework.data
spring-data-elasticsearch
${version}.RELEASE
因为原来的配置不支持了
配置文件如下:
@Configuration
public class EsConf {
@Value("${elasticSearch.url}")
private String edUrl;
//localhost:9200 写在配置文件中就可以了
@Bean
RestHighLevelClient client() {
ClientConfiguration clientConfiguration = ClientConfiguration.builder()
.connectedTo(edUrl)//elasticsearch地址
.build();
return RestClients.create(clientConfiguration).rest();
}
}
关于实体类中的几个注解,不清楚的可以去查看文档,这里不过多介绍了
@Data
@Document(indexName = "user")//索引名称 建议与实体类一致
public class User {
@Id
private Integer id;
@Field(type = FieldType.Auto)//自动检测类型
private Integer age;
@Field(type = FieldType.Keyword)//手动设置为keyword 但同时也就不能分词
private String name;
@Field(type = FieldType.Text,analyzer = "ik_smart",searchAnalyzer = "ik_max_word")//设置为text 可以分词
private String info;
}
ElasticsearchRepository<,>
第一个就是所准备的实体类,第二个是id的类型
继承完这个会提供最基本的增删改查方法,也可以自己定义一些,自己定义的方法命名需要符合规则,并不需要自己去实现
public interface EsUserService extends ElasticsearchRepository {
//根据name查询
List findByName(String name);
//根据name和info查询
List findByNameAndInfo(String name,String info);
}
“推荐下自己做的 Spring Cloud 的实战项目:
https://github.com/YunaiV/onemall
这里直接使用假数据并没有连接数据库,还需要注意几个点:
elasticsearchTemplate需要采用ElasticsearchRestTemplate 原来的已经过时了
elasticsearch的mapping没有自动生成,这导致了我们在实体类中指定的分词器没有生效,所以我在导入数据的同时,手动导入了mapping
LogAnnotation是我自定义的注解,大家可以直接去掉
controller如下:
@RestController
public class EsController {
@Autowired
private ElasticsearchRestTemplate elasticsearchTemplate;
@Autowired
private EsUserService esUserService;
private String[] names={"诸葛亮","曹操","李白","韩信","赵云","小乔","狄仁杰","李四","诸小明","王五"};
private String[] infos={"我来自中国的一个小乡村,地处湖南省","我来自中国的一个大城市,名叫上海,人们称作魔都"
,"我来自东北,家住大囤里,一口大碴子话"};
@LogAnnotation(requestRemark = "存数据")
@GetMapping("saveUser")
public ResultVO saveUser(){
//添加索引mapping 索引会自动创建但mapping自只用默认的这会导致分词器不生效 所以这里我们手动导入mapping
elasticsearchTemplate.putMapping(User.class);
Random random = new Random();
List users = new ArrayList<>();
for (int i=0;i<20;i++){
User user = new User();
user.setId(i);
user.setName(names[random.nextInt(9)]);
user.setAge(random.nextInt(40)+i);
user.setInfo(infos[random.nextInt(2)]);
users.add(user);
}
Iterable users1 = esUserService.saveAll(users);
return new ResultVO(users1);
}
@LogAnnotation(requestRemark = "根据id查询数据")
@GetMapping("getDataById")
public ResultVO getDataById(Integer id){
return new ResultVO(esUserService.findById(id));
}
@LogAnnotation(requestRemark = "分页查询所有数据")
@GetMapping("getAllDataByPage")
public ResultVO getAllDataByPage(){
//本该传入page和size,这里为了方便就直接写死了
Pageable page = PageRequest.of(0,10, Sort.Direction.ASC,"id");
Page all = esUserService.findAll(page);
return new ResultVO(all.getContent());
}
@LogAnnotation(requestRemark = "根据名字查询")
@GetMapping("getDataByName")
public ResultVO getDataByName(String name){
return new ResultVO(esUserService.findByName(name));
}
@LogAnnotation(requestRemark = "根据名字和介绍查询")
@GetMapping("getDataByNameAndInfo")
public ResultVO getDataByNameAndInfo(String name,String info){
//这里是查询两个字段取交集,即代表两个条件需要同时满足
return new ResultVO(esUserService.findByNameAndInfo(name,info));
}
}
测试结果:
@LogAnnotation(requestRemark = "查询高亮显示")
@GetMapping("getHightByUser")
public ResultVO getHightByUser(String value){
//根据一个值查询多个字段 并高亮显示 这里的查询是取并集,即多个字段只需要有一个字段满足即可
//需要查询的字段
BoolQueryBuilder boolQueryBuilder= QueryBuilders.boolQuery()
.should(QueryBuilders.matchQuery("info",value))
.should(QueryBuilders.matchQuery("name",value));
//构建高亮查询
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
.withQuery(boolQueryBuilder)
.withHighlightFields(
new HighlightBuilder.Field("info")
,new HighlightBuilder.Field("name"))
.withHighlightBuilder(new HighlightBuilder().preTags("").postTags(""))
.build();
//查询
SearchHits search = elasticsearchTemplate.search(searchQuery, User.class);
//得到查询返回的内容
List> searchHits = search.getSearchHits();
//设置一个最后需要返回的实体类集合
List users = new ArrayList<>();
//遍历返回的内容进行处理
for(SearchHit searchHit:searchHits){
//高亮的内容
Map> highlightFields = searchHit.getHighlightFields();
//将高亮的内容填充到content中
searchHit.getContent().setName(highlightFields.get("name")==null ? searchHit.getContent().getName():highlightFields.get("name").get(0));
searchHit.getContent().setInfo(highlightFields.get("info")==null ? searchHit.getContent().getInfo():highlightFields.get("info").get(0));
//放到实体类中
users.add(searchHit.getContent());
}
return new ResultVO(users);
}
测试结果:
欢迎加入我的知识星球,一起探讨架构,交流源码。加入方式,长按下方二维码噢:
已在知识星球更新源码解析如下:
最近更新《芋道 SpringBoot 2.X 入门》系列,已经 101 余篇,覆盖了 MyBatis、Redis、MongoDB、ES、分库分表、读写分离、SpringMVC、Webflux、权限、WebSocket、Dubbo、RabbitMQ、RocketMQ、Kafka、性能测试等等内容。
提供近 3W 行代码的 SpringBoot 示例,以及超 6W 行代码的电商微服务项目。
获取方式:点“在看”,关注公众号并回复 666 领取,更多内容陆续奉上。
文章有帮助的话,在看,转发吧。
谢谢支持哟 (*^__^*)