Spring Data Elasticsearch中CrudRepository路由支持问题咨询
Spring Data Elasticsearch 中 CrudRepository#findById 与 Routing 相关问题解答
问题1:当_id与_routing不一致时,CrudRepository#findById是否无用甚至误导?
- 确实会出现无效或误导性结果。默认情况下,
CrudRepository#findById仅依据_id发起查询,不会携带routing信息。在多分片索引场景中,Elasticsearch依赖routing值计算文档所在分片,缺少正确routing时,请求会被广播至所有分片,既影响性能,更关键的是:若文档_routing与_id不一致,仅用_id查询可能无法定位到目标文档(请求未发送至正确分片),甚至返回错误结果(其他分片存在相同_id的文档),此时该方法完全不适用,还会误导开发人员误判文档状态或查询结果正确性。
问题2:无需手动构建搜索请求,通过id和routing查找文档的方法?
有几种便捷方案,无需手动编写SearchRequest:
- 使用
ElasticsearchOperations工具类:直接调用elasticsearchOperations.get()方法,通过Query构建器指定id和routing,示例代码:
Query query = Query.builder() .withIds(Collections.singletonList("target-id")) .withRouting("target-routing") .build(); YourEntity entity = elasticsearchOperations.get(query, YourEntity.class);
- 自定义Repository方法:在Repository接口中添加带
@Routing注解的方法,示例:
public interface YourEntityRepository extends CrudRepository<YourEntity, String> { @Query("{\"match\": {\"_id\": {\"query\": \"?0\"}}}") YourEntity findByIdWithRouting(@Param("id") String id, @Param("routing") @Routing String routing); }
- 实体类绑定路由字段:若实体有固定路由字段,可在
@Document注解中通过routingField指定,查询时会自动携带该字段值作为routing。示例:
@Document(indexName = "your-index", routingField = "userId") public class YourEntity { @Id private String id; private String userId; // 指定为路由字段 // 其他字段及getter/setter }
此时调用自定义查询方法(如findById(String id)),只要实体中userId有值,Spring Data Elasticsearch会自动将其作为routing参数发送请求。
内容的提问来源于stack exchange,提问作者puppylpg
相关产品推荐
相关产品推荐

