Skip to content
欢迎扫码关注公众号

ElasticsearchRepository 查询时返回指定的字段

索引中的字段太多,但是只需要其中的部分字段时,可以通过 ElasticsearchRepository 中的 Page<T> search(SearchQuery searchQuery); 方法配合 NativeSearchQueryBuilder 来实现。

通过 NativeSearchQueryBuilder.withFields 方法指定需要返回的字段,其定义如下:

java
public NativeSearchQueryBuilder withFields(String... fields) {
    this.fields = fields;
    return this;
}

查询示例:

java
SearchQuery searchQuery = new NativeSearchQueryBuilder()
    .withFilter(filterBuilder)
    .withQuery(queryBuilder)
    .withPageable(PageRequest.of(0, 1, Sort.by("createTime").descending()))
    .withFields("id", "novelIds", "position")
    .build();

Page<RecommendStrategyEo> page = this.recommendStrategyRepository.search(searchQuery);

附一下完整的示例代码。

  1. 添加 spring-boot-starter-data-elasticsearch 依赖

    xml
    <!-- ElasticSearch -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
        <version>2.2.13.RELEASE</version>
    </dependency>
  2. 添加配置

    yaml
    spring:
      elasticsearch:
        rest:
          uris: ["http://172.0.0.1:9200"]
          username: guest
          password: guest
  3. 定义索引模型

    使用 @Document 注解指定索引名。
    使用 @Id 注解标记索引主键字段。
    使用 @Field 注解指定字段的类型,如下面代码中的 @Field(type = FieldType.Date) 指定字段为日期型(否则默认是 long 型)。

    注意:

    应用启动时,若索引还未创建,默认会自动创建,此时索引的 mapping 中只有使用 @Field 注解指定了类型的字段,其它字段会在保存索引文档时自动创建。
    索引未创建时查询,若ES未开启查询时自动创建索引,则会报 index_not_found_exception 异常;若开启了查询时自动创建索引,则会自动创建索引(不太确定此时字段的类型是否和注解中一致,印象中是不一致的)。
    如果应用运行过程中删除了索引,此时往索引中添加数据时,其字段的类型和注解是不一致的。所以在应用运行过程中,最好不要删除索引。

    java
    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;
    
    import java.util.Date;
    import java.util.List;
    
    @Data
    @Document(indexName = "recommend-strategy")
    public class RecommendStrategyEo {
    
        @Id
        private Integer id;
    
        private String appId;
    
        private Integer dimension;
    
        private Integer userSource;
    
        private Integer module;
    
        private Integer position;
    
        private Integer status;
    
        @Field(type = FieldType.Date)
        private Date createTime;
    
        @Field(type = FieldType.Date)
        private Date updateTime;
    
        private List<Integer> novelIds;
    
        private List<String> userCodes;
    }
  4. 创建一个继承自 ElasticsearchRepository 的接口,并添加 @Repository 注解

    ElasticsearchRepository 接口有两个泛型类型,第一个是索引对应的实体类型,第二是索引主键的类型。

    java
    import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
    import org.springframework.stereotype.Repository;
    
    @Repository
    public interface RecommendStrategyRepository
        extends ElasticsearchRepository<RecommendStrategyEo, Integer> {
    
    }
  5. 查询示例

    java
    BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
    
    queryBuilder.should(
        QueryBuilders.boolQuery()
            .must(QueryBuilders.matchQuery("dimension", RecommendStrategyDimension.Customize.getValue()))
            .must(QueryBuilders.matchQuery("userCodes", userCode))
    );
    
    queryBuilder.should(
        QueryBuilders.boolQuery()
            .must(QueryBuilders.matchQuery("dimension", RecommendStrategyDimension.UserSource.getValue()))
            .must(QueryBuilders.matchQuery("userSource", userSource))
    );
    
    BoolQueryBuilder filterBuilder = QueryBuilders.boolQuery();
    filterBuilder.must(QueryBuilders.matchQuery("appId", appId));
    filterBuilder.must(QueryBuilders.matchQuery("module", module));
    
    SearchQuery searchQuery = new NativeSearchQueryBuilder()
        .withFilter(filterBuilder)
        .withQuery(queryBuilder)
        .withPageable(PageRequest.of(0, 1, Sort.by("createTime").descending()))
        .withFields("id", "novelIds", "position")
        .build();
    
    Page<RecommendStrategyEo> page = this.recommendStrategyRepository.search(searchQuery);
    if (page == null
            || page.getContent() == null
            || page.getContent().size() == 0) {
        return null;
    }
    
    RecommendStrategyEo eo = page.getContent().get(0);
    RecommendStrategyVo vo = new RecommendStrategyVo();
    vo.setNovelIds(eo.getNovelIds());
    vo.setPosition(eo.getPosition());
    return vo;

Page Layout Max Width

Adjust the exact value of the page width of VitePress layout to adapt to different reading needs and screens.

Adjust the maximum width of the page layout
A ranged slider for user to choose and customize their desired width of the maximum width of the page layout can go.

Content Layout Max Width

Adjust the exact value of the document content width of VitePress layout to adapt to different reading needs and screens.

Adjust the maximum width of the content layout
A ranged slider for user to choose and customize their desired width of the maximum width of the content layout can go.