ElasticsearchRepository 查询时返回指定的字段
索引中的字段太多,但是只需要其中的部分字段时,可以通过 ElasticsearchRepository
中的 Page<T> search(SearchQuery searchQuery);
方法配合 NativeSearchQueryBuilder
来实现。
通过 NativeSearchQueryBuilder.withFields
方法指定需要返回的字段,其定义如下:
public NativeSearchQueryBuilder withFields(String... fields) {
this.fields = fields;
return this;
}
查询示例:
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);
附一下完整的示例代码。
添加 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>
添加配置
yamlspring: elasticsearch: rest: uris: ["http://172.0.0.1:9200"] username: guest password: guest
定义索引模型
使用
@Document
注解指定索引名。
使用@Id
注解标记索引主键字段。
使用@Field
注解指定字段的类型,如下面代码中的@Field(type = FieldType.Date)
指定字段为日期型(否则默认是long
型)。注意:
应用启动时,若索引还未创建,默认会自动创建,此时索引的 mapping 中只有使用
@Field
注解指定了类型的字段,其它字段会在保存索引文档时自动创建。
索引未创建时查询,若ES未开启查询时自动创建索引,则会报 index_not_found_exception 异常;若开启了查询时自动创建索引,则会自动创建索引(不太确定此时字段的类型是否和注解中一致,印象中是不一致的)。
如果应用运行过程中删除了索引,此时往索引中添加数据时,其字段的类型和注解是不一致的。所以在应用运行过程中,最好不要删除索引。javaimport 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; }
创建一个继承自
ElasticsearchRepository
的接口,并添加@Repository
注解ElasticsearchRepository
接口有两个泛型类型,第一个是索引对应的实体类型,第二是索引主键的类型。javaimport org.springframework.data.elasticsearch.repository.ElasticsearchRepository; import org.springframework.stereotype.Repository; @Repository public interface RecommendStrategyRepository extends ElasticsearchRepository<RecommendStrategyEo, Integer> { }
查询示例
javaBoolQueryBuilder 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;