路由值

当 Elasticsearch 将文档存储在具有多个分片的索引中时,它会根据文档的 ID 确定要使用的分片。 有时需要预定义应在同一分片上为多个文档编制索引(联接类型,更快地搜索相关数据)。 为此,Elasticsearch 提供了定义路由的可能性,该路由是应用于计算分片的值,而不是 idspring-doc.cadn.net.cn

Spring Data Elasticsearch 支持通过以下方式存储和检索数据进行路由定义:spring-doc.cadn.net.cn

在 join-types 上路由

当使用 join-types 时(参见 join-type 实现),Spring Data Elasticsearch 将自动使用parent实体的JoinField属性作为路由的值。spring-doc.cadn.net.cn

这适用于父子关系只有一个级别的所有用例。 如果它更深,例如子-父-祖父关系 - 如上面 vote → 回答问题的示例 - 则需要使用下一节中描述的技术显式指定路由(投票需要 question.id 作为路由值)。spring-doc.cadn.net.cn

自定义路由值

为了定义实体的自定义路由,Spring Data Elasticsearch 提供了一个@Routing注解(重用Statementclass 来自上面):spring-doc.cadn.net.cn

@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 的属性

如果routing注释的规范是一个纯字符串,而不是 SPEL 表达式,它被解释为实体的属性名称,在示例中它是路由属性。 然后,此属性的值将用作使用该实体的所有请求的路由值。spring-doc.cadn.net.cn

我们也可以在@Document注解,如下所示:spring-doc.cadn.net.cn

@Document(indexName = "statements")
@Routing("@myBean.getRouting(#entity)")
public class Statement{
    // all the needed stuff
}

在这种情况下,用户需要提供一个名为 myBean 的 bean,该 bean 具有一个方法String getRouting(Object).要引用实体,必须在 SPEL 表达式中使用“#entity”,并且返回值必须为null或将路由值指定为 String。spring-doc.cadn.net.cn

如果 plain property 的名称和 SPEL 表达式不足以自定义路由定义,则可以定义 provide 的RoutingResolver接口。然后,可以在ElasticOperations实例:spring-doc.cadn.net.cn

RoutingResolver resolver = ...;

ElasticsearchOperations customOperations= operations.withRouting(resolver);

withRouting()函数返回原始ElasticsearchOperations实例。spring-doc.cadn.net.cn

如果实体存储在 Elasticsearch 中,则在实体上定义了路由,则在执行 getdelete作时必须提供相同的值。对于不使用实体的方法 - 如get(ID)delete(ID)-这ElasticsearchOperations.withRouting(RoutingResolver)method 可以像这样使用:spring-doc.cadn.net.cn

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。