_routing field
_routing
field
A document is routed to a particular shard in an index using the following formulas:
routing_factor = num_routing_shards / num_primary_shards
shard_num = (hash(_routing) % num_routing_shards) / routing_factor
num_routing_shards
is the value of the index.number_of_routing_shards index setting. num_primary_shards
is the value of the index.number_of_shards index setting.
The default _routing
value is the document’s _id. Custom routing patterns can be implemented by specifying a custom routing
value per document. For instance:
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
This document uses | |
The same |
The value of the _routing
field is accessible in queries:
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);
GET my-index-000001/_search
{
"query": {
"terms": {
"_routing": [ "user1" ]
}
}
}
Querying on the |
Data streams do not support custom routing unless they were created with the allow_custom_routing setting enabled in the template.
Searching with custom routing
Custom routing can reduce the impact of searches. Instead of having to fan out a search request to all the shards in an index, the request can be sent to just the shard that matches the specific routing value (or values):
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);
GET my-index-000001/_search?routing=user1,user2
{
"query": {
"match": {
"title": "document"
}
}
}
This search request will only be executed on the shards associated with the |
Making a routing value required
When using custom routing, it is important to provide the routing value whenever indexing, getting, deleting, or updating a document.
Forgetting the routing value can lead to a document being indexed on more than one shard. As a safeguard, the _routing
field can be configured to make a custom routing
value required for all CRUD operations:
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);
PUT my-index-000002
{
"mappings": {
"_routing": {
"required": true
}
}
}
PUT my-index-000002/_doc/1
{
"text": "No routing value provided"
}
Routing is required for all documents. | |
This index request throws a |
Unique IDs with custom routing
When indexing documents specifying a custom _routing
, the uniqueness of the _id
is not guaranteed across all of the shards in the index. In fact, documents with the same _id
might end up on different shards if indexed with different _routing
values.
It is up to the user to ensure that IDs are unique across the index.
Routing to an index partition
An index can be configured such that custom routing values will go to a subset of the shards rather than a single shard. This helps mitigate the risk of ending up with an imbalanced cluster while still reducing the impact of searches.
This is done by providing the index level setting index.routing_partition_size at index creation. As the partition size increases, the more evenly distributed the data will become at the expense of having to search more shards per request.
When this setting is present, the formulas for calculating the shard become:
routing_value = hash(_routing) + hash(_id) % routing_partition_size
shard_num = (routing_value % num_routing_shards) / routing_factor
That is, the _routing
field is used to calculate a set of shards within the index and then the _id
is used to pick a shard within that set.
To enable this feature, the index.routing_partition_size
should have a value greater than 1 and less than index.number_of_shards
.
Once enabled, the partitioned index will have the following limitations:
- Mappings with join field relationships cannot be created within it.
- All mappings within the index must have the
_routing
field marked as required.