为什么写这篇文章
网上大量关于 jpa + mysql 动态条件查询的博客,但缺少 jpa + es 动态条件查询博客,找到的都是质量不高的文章,不能真正跑通 如果不用动态条件查询,当有多个条件进行查询时就非常麻烦,例如有 4 个参数,则一共要写 4 * 3 * 2 * 1 查询语句
依赖
< dependency> < groupId> org.springframework.boot< /groupId> < artifactId> spring-boot-starter-data-jpa< /artifactId> < version> 2.3 .12.RELEASE< /version> < /dependency> < dependency> < groupId> org.springframework.boot< /groupId> < artifactId> spring-boot-starter-data-elasticsearch< /artifactId> < version> 2.3 .12.RELEASE< /version> < /dependency>
实体类
package cn.xxx.api.project.dal.es.dataobject; import lombok.Data;
import lombok.ToString;
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;
import org.springframework.data.elasticsearch.annotations.GeoPointField;
import org.springframework.data.elasticsearch.core.geo.GeoPoint; @Data
@Document( indexName = "user_index" )
@ToString
public class EsUserDO { @Idprivate Long id ; @Field( type = FieldType.Long) private Long appId; /** 用户昵称 */@Field( type = FieldType.Keyword) private String name; @Field( type = FieldType.Keyword) private String sex; @Field( type = FieldType.Boolean) private Boolean available;
}
DAO
package cn.xxx.api.project.dal.es.dao; import cn.xxx.api.project.dal.es.dataobject.EsUserDO;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.stereotype.Repository; import java.util.List; @Repository
public interface EsUserDAO extends ElasticsearchRepository< EsUserDO, Long> {
}
动态条件查询
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable; /*** es 动态条件查询用户信息** @param appId 应用ID* @param name 用户名* @param sex 性别* @param available 是否可用* @param page 第几页(从 1 开始)* @param size 每页条数* @return*/
public Page< EsUserDO> searchUsers( Long appId, String name, String sex, Boolean available, Integer page, Integer size) { log.debug( "searchUsers-start appId : {} name : {} sex : {} available : {} page : {} size : {}" , appId, name, sex, available, sex, page, size) ; Pageable pageable = PageRequest.of( page - 1 , size) ; BoolQueryBuilder boolQuery = QueryBuilders.boolQuery( ) ; if ( Objects.nonNull( appId)) { boolQuery.must( QueryBuilders.termQuery( "appId" , appId)) ; } if ( StringUtils.isNotEmpty( name)) { boolQuery.must( QueryBuilders.termQuery( "name" , name)) ; } if ( StringUtils.isNotEmpty( sex)) { boolQuery.must( QueryBuilders.termQuery( "sex" , sex)) ; } if ( Objects.nonNull( available)) { if ( available) { boolQuery.must( QueryBuilders.termQuery( "available" , available)) ; } else { // 查询 available 为 false 或者不存在该字段的数据BoolQueryBuilder shouldQuery = QueryBuilders.boolQuery( ) .should( QueryBuilders.termQuery( "available" , available)) .should( QueryBuilders.boolQuery( ) .mustNot( QueryBuilders.existsQuery( "available" )) ) ; boolQuery.must( shouldQuery) ; } } Page< EsUserDO> search = esUserDAO.search( boolQuery, pageable) ; log.info( "searchUsers-end boolQuery : {} search : {}" , boolQuery.toString( ) , JSON.toJSONString( search)) ; return search;
}