spring-data-elasticsearch使用Sort排序时Please use a keyword field instead. ……异常解决
Please use a keyword field instead. Alternatively, set fielddata=true on [dataTimestamp] in order to load field data by uninverting the inverted index.需要配置FieldType.Keyword或fielddata = true,可是代码中都配置了还
异常信息
核心提示在Please use a keyword field instead. Alternatively, set fielddata=true on [dataTimestamp] in order to load field data by uninverting the inverted index.
待排序字段dataTimestamp
没有为排序优化,所以无法排序,需要配置FieldType.Keyword
或fielddata = true
,可是代码中都配置了为什么还提示呢,往下看……
Elasticsearch exception [type=search_phase_execution_exception, reason=all shards failed];
nested exception is ElasticsearchStatusException
[Elasticsearch exception [type=search_phase_execution_exception, reason=all shards failed]];
nested: ElasticsearchException[Elasticsearch exception
[type=illegal_argument_exception, reason=Text fields are not optimised for operations that require per-document field data like aggregations and sorting, so these operations are disabled by default.
Please use a keyword field instead. Alternatively, set fielddata=true on [dataTimestamp] in order to load field data by uninverting the inverted index.
Note that this can use significant memory.]]; nested: ElasticsearchException[Elasticsearch exception [type=illegal_argument_exception, reason=Text fields are not optimised for operations that require per-document field data like aggregations and sorting, so these operations are disabled by default. Please use a keyword field instead. Alternatively, set fielddata=true on [dataTimestamp] in order to load field data by uninverting the inverted index. Note that this can use significant memory.]]
环境
spring-data-elasticsearch 4.1.3
ElasticSearch 7.9.3
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-elasticsearch</artifactId>
<version>4.1.3</version>
</dependency>
spring-data-elasticsearch这块,对ElasticSearch 7.16之前的都差不多,相似版本可以尝试
代码配置
ElasticSearch实体
如下配置,异常提示需要将排序字段设置为Keyword类型(推荐),或者将fielddata设置为true(不推荐),可是我都设置了,还是提示上面的
注意:这里使用Spring ElasticSearch注解是否生效一定要注意,如果注解未生效就会导致声明的索引、字段信息都是无效的,所以配置了也没有,下面说如何检查
@Data
@Document(indexName = "test-index")
public class ElasticSearchEntity {
/**
* ElasticSearch Long型精度会丢失
*/
@Id
@Field(type = FieldType.Keyword)
private String dataId;
// 配置二选一即可,推荐FieldType.Keyword,使用fielddata = true相对更占资源
@Field(type = FieldType.Keyword, fielddata = true)
private String dataTimestamp;
}
检查ElasticSearch实体映射结果
项目启动后会自动在ElasticSearch创建索引,查询索引信息,有mapping才说明注解配置生效了,因为注解声明的字段信息在ElasticSearch对应的就是mapping
如果没有请检查,Java日志是否有如下类似的创建失败警告
,按照警告提示修改实体注解配置,尝试至无警告创建,再到ElasticSearch查询索引是否正确加载mapping
[o.s.d.e.r.s.SimpleElasticsearchRepository,<init> : 96] - Cannot create index: Elasticsearch exception [type=mapper_parsing_exception, reason=Mapping definition for
ElasticSearch数据操作接口
public interface IndexRepository extends ElasticsearchRepository<ElasticSearchEntity, String> {
}
查询调用(高级查询接口自定义)
这里先列出来两种写法,因为mapping字段声明未加载成功可导致使用时的问题,推荐第一种,所以上面如果有问题的检查一下
Criteria criteria = new Criteria("title").contains(keyword);
// 1、没有加载mapping默认识别string类型,如果keyword声明加载成功这么写就可以了(推荐这种,所以上面如果有问题的检查一下)
Sort sort = Sort.by("_score", "dataTimestamp").descending();
// 2、没有加载mapping默认为string类型创建keyword,Keyword类型才有索引可以排序,想使用Keyword索引要加.keyword使用,否则还是原字段
Sort sort = Sort.by("_score", "dataTimestamp.keyword").descending();
Query query = new CriteriaQuery(criteria)
.setPageable(
PageRequest.of(pageNum, pageSize, sort)
);
SearchHits<ElasticSearchEntity> searchHits = elasticsearchRestTemplate.search(query, ElasticSearchEntity.class, IndexCoordinates.of("index-*"));
发现问题
各种查文档,都没有对spring-data-elasticsearch的这个异常处理方案,所以只能自己查了
既然是ElasticSearch的错误就去原生查询,查询时发现,ElasticSearch的dataTimestamp的字段有两个,因为没有加载mapping默认识别string类型,默认还会为string类型创建keyword,所以这时候有两种类型,使用的时候就要注意调用区分,如果keyword声明成功,就只有一个keyword类型,直接使用原字段就可以
原因
查询ElasticSearch文档对keyword的介绍,大致说一下我的理解,有问题望指正
Keyword是相当于对Text的一个补充,设置Keyword类型或当Text设置分词器、索引的时候,就会创建一个.keyword字段,用于更快速的查询,所以文本字段需要使用索引时,不可以直接使用原字段,要利用.keyword字段操作就可以了
更多推荐
所有评论(0)