路由值
当 Elasticsearch 将文档存储在具有多个分片的索引中时,它会根据文档的id确定要使用的分片。有时需要预先定义多个文档应索引在同一个分片上(连接类型、更快地搜索相关数据)。为此,Elasticsearch 提供了定义路由的可能性,路由是应代替id用于计算分片的值。
Spring Data Elasticsearch 通过以下方式支持数据存储和检索中的路由定义
连接类型上的路由
使用连接类型时(参见连接类型实现),Spring Data Elasticsearch 将自动使用实体JoinField属性的parent属性作为路由的值。
这对于所有父子关系只有一个级别的用例都是正确的。如果它更深,例如子-父-祖父关系 - 就像上面来自vote → answer → question的示例一样 - 那么需要使用下一节中描述的技术明确指定路由(vote需要question.id作为路由值)。
自定义路由值
要为实体定义自定义路由,Spring Data Elasticsearch 提供了@Routing注解(重用上面的Statement类)
@Document(indexName = "statements")
@Routing("routing") (1)
public class Statement {
@Id
private String id;
@Field(type = FieldType.Text)
private String text;
@JoinTypeRelations(
relations =
{
@JoinTypeRelation(parent = "question", children = {"answer", "comment"}),
@JoinTypeRelation(parent = "answer", children = "vote")
}
)
private JoinField<String> relation;
@Nullable
@Field(type = FieldType.Keyword)
private String routing; (2)
// getter/setter...
}
| 1 | 这将“routing”定义为路由规范 |
| 2 | 一个名为routing的属性 |
如果注解的routing规范是纯字符串而不是 SpEL 表达式,它将被解释为实体属性的名称,在示例中是routing属性。此属性的值将用作使用该实体的所有请求的路由值。
也可以在@Document注解中使用 SpEL 表达式,如下所示
@Document(indexName = "statements")
@Routing("@myBean.getRouting(#entity)")
public class Statement{
// all the needed stuff
}
在这种情况下,用户需要提供一个名为myBean的 bean,该 bean 具有方法String getRouting(Object)。要引用实体,必须在 SpEL 表达式中使用"#entity",并且返回值必须为null或作为字符串的路由值。
如果纯属性名称和 SpEL 表达式不足以自定义路由定义,则可以提供RoutingResolver接口的实现。然后可以在ElasticOperations实例上设置它
RoutingResolver resolver = ...;
ElasticsearchOperations customOperations= operations.withRouting(resolver);
withRouting()函数返回原始ElasticsearchOperations实例的副本,并设置了自定义路由。
当在 Elasticsearch 中存储实体时已定义路由,则在执行get或delete操作时必须提供相同的值。对于不使用实体的方法 - 例如get(ID)或delete(ID) - ElasticsearchOperations.withRouting(RoutingResolver)方法可以这样使用
String id = "someId";
String routing = "theRoutingValue";
// get an entity
Statement s = operations
.withRouting(RoutingResolver.just(routing)) (1)
.get(id, Statement.class);
// delete an entity
operations.withRouting(RoutingResolver.just(routing)).delete(id);
| 1 | RoutingResolver.just(s)返回一个将只返回给定字符串的解析器。 |