对于最新的稳定版本,请使用 Spring Data Elasticsearch 5.4.0! |
路由值
当 Elasticsearch 将文档存储在具有多个分片的索引中时,它会根据文档的 ID 确定要使用的分片。 有时需要预定义应在同一分片上为多个文档编制索引(联接类型,更快地搜索相关数据)。 为此,Elasticsearch 提供了定义路由的可能性,该路由是应用于计算分片的值,而不是 id。
Spring Data Elasticsearch 支持通过以下方式存储和检索数据的路由定义:
在 join-types 上路由
当使用连接类型时(参见连接类型实现),Spring Data Elasticsearch 将自动使用实体属性的属性作为路由的值。parent
JoinField
这适用于父子关系只有一个级别的所有用例。 如果它更深,比如子-父-祖父关系 - 如上面 vote → 回答→问题的例子 - 那么路由需要使用下一节中描述的技术显式指定(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” 定义为 routing 规范 |
2 | 名称为 routing 的属性 |
如果 Comments 的规范是纯字符串而不是 SPEL 表达式,则它将被解释为实体的属性名称,在本例中它是路由属性。
然后,此属性的值将用作使用该实体的所有请求的路由值。routing
我们也可以在 Comments 中使用 SpEL 表达式,如下所示:@Document
@Document(indexName = "statements")
@Routing("@myBean.getRouting(#entity)")
public class Statement{
// all the needed stuff
}
在这种情况下,用户需要提供一个名为 myBean 的 bean,该 bean 具有 method 。要引用实体,必须在 SPEL 表达式中使用“#entity”,并且返回值必须是 或 路由值作为 String。String getRouting(Object)
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) 返回一个解析程序,该解析程序将仅返回给定的 String。 |