es-elasticsearch-SpringBootDataElasticsearch在springboot中的使用

26 篇文章 0 订阅

探讨

分词问题

保存的数据text会被分词,term搜索内容不分词,match搜索内容分词:https://blog.csdn.net/egg1996911/article/details/82380026
https://www.cnblogs.com/austinspark-jessylu/p/6878370.html

所以可以用逗号作为分词的依据

        if (CollectionUtils.isNotEmpty(searchDataReqDTO.getCopyrightIds())) {
            filterBuilder.must(new MatchQueryBuilder("copyrightId", searchDataReqDTO.getCopyrightIds().stream().collect(Collectors.joining(","))));
        }

一,依赖

依赖这块,springboot的版本2.0.9.RELEASE和2.2.5.RELEASE都启动出现异常,后来使用2.3.0.RELEASE就可以启动,2.1.14.RELEASE也可以。
但是实际启动发现es的客户端和服务端的版本不匹配,因为连接了本地。。。后来删除了高阶依赖,将nacos的版本调整就可以了读取到配置了。
这里注意不能写版本号,让系统自己找到合适的版本。

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

配置

项目的

spring.data.elasticsearch.name.cluster-name=elasticsearch
spring.data.elasticsearch.name.cluster‐nodes=10.88.130.97:9300
spring.data.elasticsearch.name.local=true
spring.data.elasticsearch.name.repositories.enable=true
management.endpoint.health.show-details=always

实际上操作发现不对,然后根据网上给的继续配置,依旧不对,老是连接127.0.0.1,
最后将高阶的依赖删除,将nacos的版本降低,就可以了。具体配置如下

#spring.data.elasticsearch.cluster-name=elasticsearch
spring.data.elasticsearch.cluster-nodes=10.88.130.97:9300
spring.data.elasticsearch.repositories.enabled=true

二,实体类

在高版本中会发现type已经过时,入库后发现实际上type是_doc

@Document(indexName = "test",type = "base")
public class User {

    @Id
    private Long id;

    @Field(type = FieldType.Keyword)
    private String name;

    @Field(type = FieldType.Text)
    private String number;

    @Field(type = FieldType.Double)
    private BigDecimal price;

    @Field(type = FieldType.Integer)
    private Integer age;

    @Field(type = FieldType.Date)
    private Date createTime;

    @Field(type = FieldType.Keyword)
    private String updateTime;
}

关于index和type

实体类可以决定index和type,切换index是消耗资源的,但是如果是使用了多个type,也是存在一个问题,虽然可以定义不同的字段,但是很明显,因为es底层高效检索的设计,一个type中存在,另一个type中不存在的时候,会在另一个的实体中分配虚拟字段,这就导致两个问题,如果字段区别大导致所有的存储都内存消耗变大,另外是相同的名字,字段类型必须保持一致,否则启动会报错。后期版本的es逐渐弱化type

参考:http://t.zoukankan.com/hanks-p-12041514.html

关于字段

text,key,long,integer,double,都是默认建立索引,注意date默认没有索引
text和key都是针对string类型,但是text是分词后建立索引,key是直接建立索引的,所以尽量使用key,如果是大文件就使用text。
Array是数组
object是json的nested 类型
join是父子关系
参考:https://www.cnblogs.com/gscq073240/articles/9533629.html

/**
 *  表示该字段是一个文本,并作最大程度拆分,默认建立索引
 */
@Field(type=FieldType.Text, analyzer="ik_max_word")    
/**
 *  表示该字段是一个文本,不建立索引
 */
@Field(type=FieldType.Text,index=false)             
/**
 *  表示该字段是一个文本,日期类型,默认不建立索引
 */
@Field(type=FieldType.Date)                                
/**
 *  表示该字段是一个长整型,默认建立索引
 */
@Field(type=FieldType.Long)                               
/**
 *  表示该字段内容是一个文本并作为一个整体不可分,默认建立索引
 */
@Field(type=FieldType.Keyword)                         
/**
 *  表示该字段内容是一个浮点类型并作为一个整体不可分,默认建立索引
 */
@Field(type=FieldType.Float)                               
 
date 、float、long都是不能够被拆分的

关系表查询

关系表查询的方式
1,应用层join,采用多次查询
2,嵌套查询,采用一个doc上存储多个nested 类型的数据,通俗的说就是数据库多张表的字段挤在一个es doc上。数据冗余
3,父子关系,查询速度慢,后期版本的es逐渐用join字段取代父子关系。

查询接口

Long是id的类型
这个是springboot默认的数据库操作,携带了便捷的方法。

public interface UserDao extends ElasticsearchRepository<User,Long> {
}

执行增删改查

@Slf4j
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserDao userDao;

    @Override
    public UserDO add(UserDO user) {
        user.setCreateTime(new Date());
        UserDO save = userDao.save(user);
        return save;
    }

    @Override
    public boolean addList(List<UserDO> list) {
        Iterable<UserDO> userDOS = userDao.saveAll(list);
        Iterator<UserDO> iterator = userDOS.iterator();
        ArrayList<UserDO> re = new ArrayList<>();
        while (iterator.hasNext()) {
            UserDO next = iterator.next();
            re.add(next);
        }
        log.info("result:{}", re);
        return re.size() > 0;
    }

    @Override
    public Iterable delete(String content) {
        //先查找拿到iterable
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.must(QueryBuilders.matchQuery(UserDO.FIELD_NAME, content));
        Iterable<UserDO> iterable = userDao.search(boolQueryBuilder);
        //然后根据iterable进行删除操作
        userDao.deleteAll(iterable);
        return iterable;
    }

    @Override
    public UserDO update(UserDO user) {
        //不存在更新,因为更新就必须知道原来的id,然后执行覆盖操作
        UserDO save = userDao.save(user);
        return save;
    }

    @Override
    public List<UserDO> search(String content) {
        //先查找拿到iterable
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.must(QueryBuilders.matchQuery(UserDO.FIELD_NAME, content));
        Iterable<UserDO> iterable = userDao.search(boolQueryBuilder);
        Iterator<UserDO> iterator = iterable.iterator();
        ArrayList<UserDO> re = new ArrayList<>();
        while (iterator.hasNext()) {
            UserDO next = iterator.next();
            re.add(next);
        }
        return re;
    }
}
// 原生的查询条件类
NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();

// 匹配所有记录
//nativeSearchQueryBuilder.withQuery(QueryBuilders.matchAllQuery());



// 查询条件构造器
BoolQueryBuilder builder = QueryBuilders.boolQuery();

BoolQueryBuilder sholdBuilderProd = QueryBuilders.boolQuery();
// 用途值模糊搜索
sholdBuilderProd.should(QueryBuilders.matchPhraseQuery("purposeValue", searchContent));
builder.must(sholdBuilderProd);


BoolQueryBuilder filterBuilder = QueryBuilders.boolQuery();
filterBuilder.must(new MatchQueryBuilder("resourceDesigner",
        String.join(",", searchDataReqDTO.getResourceDesignerIds().stream().collect(Collectors.joining(",")))));
filterBuilder.must(QueryBuilders.termsQuery("updaterUserId",searchDataReqDTO.getUpdaterUserIds()));
builder.must(filterBuilder);


builder.filter(QueryBuilders.rangeQuery("weightStart").gte(searchDataReqDTO.getMinWeight()));

nativeSearchQueryBuilder.withQuery(builder);
nativeSearchQueryBuilder.withFilter(builder);
// 排序规则: 按搜索匹配度从高到低排序(名称匹配权重最高)
nativeSearchQueryBuilder.withSort(SortBuilders.scoreSort());
// ES分页从0开始
PageRequest pageRequest = null;
if (searchDataReqDTO.getPage() != null) {
    pageRequest = PageRequest.of((int) searchDataReqDTO.getPage().getPageNum() - 1, (int) searchDataReqDTO.getPage().getPageSize());
} else {
    pageRequest = PageRequest.of(0, 50);
}
nativeSearchQueryBuilder.withPageable(pageRequest);
// 执行查询
NativeSearchQuery searchQuery = nativeSearchQueryBuilder.build();
Page<ResourceSearchData> resourceSearchData = iResourceSearchDataRepository.search(searchQuery);

springboot集成不被支持

参考:https://blog.csdn.net/weixin_44600430/article/details/117203834
本地启动的es是7版本的,依赖并没有控制es的版本,加载的是7版本的依赖,在执行方法的时候,会发现search方法已经过时了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值