_routing 字段编辑

使用以下公式将文档路由到索引中的特定分片

routing_factor = num_routing_shards / num_primary_shards
shard_num = (hash(_routing) % num_routing_shards) / routing_factor

num_routing_shardsindex.number_of_routing_shards 索引设置的值。 num_primary_shardsindex.number_of_shards 索引设置的值。

默认的 _routing 值是文档的 _id。可以通过为每个文档指定自定义 routing 值来实现自定义路由模式。例如

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
PUT my-index-000001/_doc/1?routing=user1&refresh=true 
{
  "title": "This is a document"
}

GET my-index-000001/_doc/1?routing=user1 

此文档使用 user1 作为其路由值,而不是其 ID。

获取删除更新 文档时,需要提供相同的 routing 值。

可以在查询中访问 _routing 字段的值

response = client.search(
  index: 'my-index-000001',
  body: {
    query: {
      terms: {
        _routing: [
          'user1'
        ]
      }
    }
  }
)
puts response
GET my-index-000001/_search
{
  "query": {
    "terms": {
      "_routing": [ "user1" ] 
    }
  }
}

_routing 字段上查询(另请参阅 ids 查询

除非数据流是在模板中启用了 allow_custom_routing 设置的情况下创建的,否则它们不支持自定义路由。

使用自定义路由进行搜索编辑

自定义路由可以减少搜索的影响。请求不必扇出到索引中的所有分片,而只需发送到与特定路由值(或多个值)匹配的分片即可

response = client.search(
  index: 'my-index-000001',
  routing: 'user1,user2',
  body: {
    query: {
      match: {
        title: 'document'
      }
    }
  }
)
puts response
GET my-index-000001/_search?routing=user1,user2 
{
  "query": {
    "match": {
      "title": "document"
    }
  }
}

此搜索请求将仅在与 user1user2 路由值关联的分片上执行。

将路由值设为必需编辑

使用自定义路由时,在 索引获取删除更新 文档时,务必提供路由值。

忘记路由值可能会导致文档被索引到多个分片上。作为一种保障措施,可以将 _routing 字段配置为使所有 CRUD 操作都需要自定义 routing

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
PUT my-index-000002
{
  "mappings": {
    "_routing": {
      "required": true 
    }
  }
}

PUT my-index-000002/_doc/1 
{
  "text": "No routing value provided"
}

所有文档都需要路由。

此索引请求会引发 routing_missing_exception

具有自定义路由的唯一 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 字段标记为必需。