_routing 字段
编辑_routing
字段
编辑文档使用以下公式路由到索引中的特定分片
routing_factor = num_routing_shards / num_primary_shards shard_num = (hash(_routing) % num_routing_shards) / routing_factor
num_routing_shards
是 index.number_of_routing_shards
索引设置的值。num_primary_shards
是 index.number_of_shards
索引设置的值。
默认的 _routing
值是文档的 _id
。可以通过为每个文档指定自定义的 routing
值来实现自定义路由模式。例如:
resp = client.index( index="my-index-000001", id="1", routing="user1", refresh=True, document={ "title": "This is a document" }, ) print(resp) resp1 = client.get( index="my-index-000001", id="1", routing="user1", ) print(resp1)
response = client.index( index: 'my-index-000001', id: 1, routing: 'user1', refresh: true, body: { title: 'This is a document' } ) puts response response = client.get( index: 'my-index-000001', id: 1, routing: 'user1' ) puts response
const response = await client.index({ index: "my-index-000001", id: 1, routing: "user1", refresh: "true", document: { title: "This is a document", }, }); console.log(response); const response1 = await client.get({ index: "my-index-000001", id: 1, routing: "user1", }); console.log(response1);
PUT my-index-000001/_doc/1?routing=user1&refresh=true { "title": "This is a document" } GET my-index-000001/_doc/1?routing=user1
在查询中可以访问 _routing
字段的值
resp = client.search( index="my-index-000001", query={ "terms": { "_routing": [ "user1" ] } }, ) print(resp)
response = client.search( index: 'my-index-000001', body: { query: { terms: { _routing: [ 'user1' ] } } } ) puts response
const response = await client.search({ index: "my-index-000001", query: { terms: { _routing: ["user1"], }, }, }); console.log(response);
在 |
数据流不支持自定义路由,除非它们是在模板中启用了 allow_custom_routing
设置的情况下创建的。
使用自定义路由进行搜索
编辑自定义路由可以减少搜索的影响。搜索请求不必扇出到索引中的所有分片,而是可以将请求仅发送到与特定路由值(或多个值)匹配的分片
resp = client.search( index="my-index-000001", routing="user1,user2", query={ "match": { "title": "document" } }, ) print(resp)
response = client.search( index: 'my-index-000001', routing: 'user1,user2', body: { query: { match: { title: 'document' } } } ) puts response
const response = await client.search({ index: "my-index-000001", routing: "user1,user2", query: { match: { title: "document", }, }, }); console.log(response);
使路由值成为必需
编辑使用自定义路由时,在索引、获取、删除或更新文档时,提供路由值非常重要。
忘记路由值可能导致文档在多个分片上建立索引。作为一种安全措施,可以配置 _routing
字段,以使所有 CRUD 操作都必须使用自定义的 routing
值
resp = client.indices.create( index="my-index-000002", mappings={ "_routing": { "required": True } }, ) print(resp) resp1 = client.index( index="my-index-000002", id="1", document={ "text": "No routing value provided" }, ) print(resp1)
response = client.indices.create( index: 'my-index-000002', body: { mappings: { _routing: { required: true } } } ) puts response response = client.index( index: 'my-index-000002', id: 1, body: { text: 'No routing value provided' } ) puts response
const response = await client.indices.create({ index: "my-index-000002", mappings: { _routing: { required: true, }, }, }); console.log(response); const response1 = await client.index({ index: "my-index-000002", id: 1, document: { text: "No routing value provided", }, }); console.log(response1);
自定义路由的唯一 ID
编辑在索引指定了自定义 _routing
的文档时,不能保证 _id
在索引的所有分片中都是唯一的。实际上,如果使用不同的 _routing
值进行索引,则具有相同 _id
的文档可能会最终出现在不同的分片上。
用户有责任确保 ID 在整个索引中是唯一的。
路由到索引分区
编辑可以配置索引,使自定义路由值将转到分片的子集,而不是单个分片。这有助于减轻最终导致集群不平衡的风险,同时仍然减少了搜索的影响。
这是通过在索引创建时提供索引级别的设置 index.routing_partition_size
来完成的。随着分区大小的增加,数据分布将变得更加均匀,但代价是每次请求必须搜索更多的分片。
当存在此设置时,用于计算分片的公式变为
routing_value = hash(_routing) + hash(_id) % routing_partition_size shard_num = (routing_value % num_routing_shards) / routing_factor
也就是说,_routing
字段用于计算索引中的一组分片,然后使用 _id
来选择该组中的分片。
要启用此功能,index.routing_partition_size
应具有大于 1 且小于 index.number_of_shards
的值。
启用后,分区索引将具有以下限制
- 无法在其内部创建具有
join
字段关系的映射。 - 索引中的所有映射都必须将
_routing
字段标记为必需。