初探Spring Data Elasticsearch

文章介绍了如何在SpringBoot项目中使用SpringDataElasticsearch来集成和操作Elasticsearch,包括引入依赖、配置、创建实体类、定义文档关系、实现仓库接口、服务层处理以及复杂查询的方法。示例展示了从创建索引到执行自定义和复杂查询的完整流程。
摘要由CSDN通过智能技术生成

个人博客dogbin.vip
essdadasdasd

Spring Data Elasticsearch 介绍

Spring Data Elasticsearch 基于 spring data API 简化 Elasticsearch 操作,将原始操作 Elasticsearch 的客户端 API 进行封装 。Spring Data 为 Elasticsearch 项目提供集成搜索引擎。

Spring Data Elasticsearch POJO 的关键功能区域为中心的模型与 Elastichsearch 交互文档和轻松地编写一个存储索引库数据访问层。

官网:Spring Data Elasticsearch

1.引入依赖并配置地址

① 在SpringBoot项目中引入Spring Data Elasticsearch的依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>

② 在 application.yml 中配置Elasticsearch的地址

spring:  
  elasticsearch:
    uris: http://192.168.10.155:9200

2.创建实体类以及对应的文档Document关系

① 创建实体类

/**
 * @author niumazlb
 * @create 2022-08-30 19:41
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@Document(indexName = "langbei")
@Setting(shards = 1,replicas = 1)
public class UserVo {

    private static final long serialVersionUID = 1L;
    /**
     * 用户id
     */
    @Id
    private long id;
    /**
     * 用户昵称
     */
    @Field(name = "username")
    private String username;
    /**
     * 用户账号
     */
    @Field(name = "userAccount",type = FieldType.Text,searchAnalyzer="ik_max_word",analyzer="ik_max_word")
    private String userAccount;
    /**
     * 用户头像
     */
    @Field(name = "avatarUrl")
    private String avatarUrl;
    /**
     * 性别
     */
    @Field(name = "gender")
    private Integer gender;
    /**
     * 标签列表
     */
    @Field(name = "tags")
    private String tags;
    /**
     * 电话
     */
    @Field(name = "phone")
    private String phone;
    /**
     * 联系方式
     */
    @Field(name = "contactInfo")
    private String contactInfo;
    /**
     * 个人简介
     */
    @Field(name = "profile")
    private String profile;
    /**
     * 用户状态
     */
    @Field(name = "userStatus")
    private Integer userStatus;
    /**
     * 创建时间
     */
    @Field(name = "createTime")
    private Date createTime;
    /**
     * 更新时间
     */
    @Field(name = "updateTime")
    private Date updateTime;
    /**
     * 是否删除
     */
    @Field(name = "isDelete")
    private Integer isDelete;
    /**
     * 用户角色 0-普通用户 1-管理员
     */
    @Field(name = "userRole")
    private Integer userRole;
    /**
     * 编号
     */
    @Field(name = "planetCode")
    private String planetCode;

}

注解介绍

@Document(indexName = “”) :

  • 指定索引库的名字,网上大多会在此注解中配置分片数、副本数,但是观察源码会发现这两个属性已经被废弃

image-20230221220406853

@Setting(shards = 1,replicas = 1) :

  • 用于声明索引库的配置,例如分片数、副本数等

image-20230221220653153

@Id,@Field(name = “”) :

  • @Id 用于声明mapper的_id,必须声明
  • @Field(…) 用于声明该字段的各个属性,比如字段名,字段类型,使用什么分词器,格式等
    • image-20230221221035647

3.创建文档的管理ElasticSearchRepository接口

① 创建 UserVoRepository

  • 继承ElasticsearchRepository<映射实体类主键数据类型>,里面有一些自带的方法
    • 新增、更新数据:使用repository的save()方法实现
    • 删除数据:deleteById()、deleteAll()
    • 查询:findById()、findAll()
  • 自定义查询方法
    • 方法名满足指定格式,就可以自定义查询方法
      • findBy{Titlte}And{contnet}(String title,String contnet);
/**
 * @author niuma
 * @create 2023-02-21 21:07
 */
@Repository
public interface UserVoRepository extends ElasticsearchRepository<UserVo,Long> {
    /**
     * 满足规定格式,可以自定义查询方法
     *  findBy{Titlte}And{contnet}(String title,String contnet)
     * @param userAccount
     * @return
     */
    List<UserVo> findByUserAccount(String userAccount);
}

4.创建service

UserVoService.java 几个简单的方法

/**
 * @author niumazlb
 */
public interface UserVoService {
    List<UserVo> findByUserAccount(String userAccount);

    void save(UserVo docBean);

    void saveAll(List<UserVo> list);

    Iterator<UserVo> findAll();
}

UserVoServiceImpl.java 实现类

/**
 * @author niumazlb
 */
@Service
public class UserVoServiceImpl implements UserVoService {

    @Resource
    private UserVoRepository elasticRepository;
    
    @Override
    public List<UserVo> findByUserAccount(String userAccount) {
       return elasticRepository.findByUserAccount(userAccount);
    }

    @Override
    public void save(UserVo docBean) {
        elasticRepository.save(docBean);
    }

    @Override
    public void saveAll(List<UserVo> list) {
        elasticRepository.saveAll(list);
    }

    @Override
    public Iterator<UserVo> findAll() {
        return elasticRepository.findAll().iterator();
    }
}

5.简单测试

  • 依次执行可以得到正确的结果
/**
 * @author niuma
 * @create 2023-02-21 21:11
 */
@SpringBootTest
class UserVoServiceTest {
    @Resource
    UserVoService userVoService;
    @Resource
    UserService userService;

    /**
     * 创建索引库以及 mapping
     */
    @Test
    void saveAll() {
        //从数据库读取数据并加入list
        List<UserVo> list = userService.list().stream().map(user -> {
            UserVo userVo = new UserVo();
            BeanUtils.copyProperties(user, userVo);
            return userVo;
        }).collect(Collectors.toList());
        //批量加入文档
        userVoService.saveAll(list);
    }

    @Test
    void findAll() {
        Iterator<UserVo> all = userVoService.findAll();
        while(all.hasNext()){
            UserVo next = all.next();
            System.out.println(next);
        }
    }
    
    @Test
    void findByUserAccount() {
        List<UserVo> userVos = userVoService.findByUserAccount("4");
        System.out.println(userVos);
    }
}

6.复杂查询

参考:SpringDataElasticSearch框架 - 掘金 (juejin.cn)

复杂查询需要使用 ElasticsearchRestTemplate对象

① 创建索引库以及mapping的方法

//创建索引库
template.indexOps(UserVo.class).create();//从对象中创建
template.indexOps(IndexCoordinates.of("langbei")).create();//指定名称创建

//创建mapping
Document mapping = template.indexOps(UserVo.class).createMapping();
template.indexOps(UserVo.class).putMapping(mapping);

② 查询

  1. 使用 NativeSearchQuery 封装查询条件
  2. SearchHits searchHits = template.search(Query query, Class<T> clazz); 执行查询并得到查询结果
  3. 对结果处理
    @Resource
    ElasticsearchRestTemplate template;

    @Test
    void testElasticsearchRestTemplate(){
        NativeSearchQuery query = new NativeSearchQueryBuilder()
                .withQuery(QueryBuilders.matchQuery("userAccount","4")) //查询条件
                .withHighlightBuilder(new HighlightBuilder().field("userAccount").preTags("<em>").postTags("</em>")) //高亮设置前后缀
                .build();
        SearchHits<UserVo> searchHits = template.search(query, UserVo.class); //执行查询
        long totalHits = searchHits.getTotalHits(); //获取查询到的条数
        System.out.println("totalHits = " + totalHits); 
        List<SearchHit<UserVo>> searchHits1 = searchHits.getSearchHits(); 
        searchHits1.forEach( e->{
            UserVo content = e.getContent();
            System.out.println("content = " + content);
            Map<String, List<String>> highlightFields = e.getHighlightFields();
            List<String> highlightUserAccount = highlightFields.get("userAccount");
            System.out.println(highlightUserAccount);
        });
    }

image-20230221224835407

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值