elasticsearch中自定义doc的路由(routing)规则
版权声明 本站原创文章 由 萌叔 发表
转载请注明 萌叔 | https://vearne.cc
1. 前言
前几天有人在群里问,es是否可以指定某个字段为路由值。ES自定义的doc的路由,不过es的操作是,在写入一个doc时,指定doc的routing key。
2. 例子
2.1 创建一个新的index
PUT /my_index2
{
  "settings": {
    "index": {
      "number_of_shards": 2,
      "number_of_replicas": 1
    }
  }
}

index只有2个shard,shard 0和 shard 1
2.2 设置mapping
PUT /my_index2/_mapping/student
{
    "_routing": {
        "required": true
    },
    "properties": {
        "name": {
            "type": "keyword"
        },
        "age": {
            "type": "integer"
        }
    }
}
2.3 指定doc路由
PUT /my_index2/student/1?routing=key1
{
    "name":"n1",
    "age":10
}
PUT /my_index2/student/2?routing=key1
{
    "name":"n2",
    "age":10
}
PUT /my_index2/student/3?routing=key1
{
    "name":"n3",
    "age":10
}
上面的3条命令会使得doc1、2、3放置在同一个shard上
shard 0

shard 1

shard 0上的doc数是0,shard 1上的doc数是3,可见doc的分布是按照我们的要求来执行的。
shard的具体编号由以下公式决定
shard_num = hash(_routing) % num_primary_shards
3. 作用
那么自定义routing到底有什么作用呢?
我们知道,正常的一次查询(search),请求会被发给所有shard(不考虑副本),然后等所有shard返回,再将结果聚合,返回给调用方。如果我们事先已经知道数据可能分布在哪些shard上,那么就可以减少不必要的请求。
GET /_search_shards?routing=key1
返回
{
    "shards": [
        [
            {
                "state": "STARTED",
                "primary": true, // 主副本
                "node": "uf_-1wJHSEqgQmgPxanZJA",
                "relocating_node": null,
                "shard": 1,  // 只需要检索`shard` 1
                "index": "my_index2",
                "allocation_id": {
                    "id": "tZzcW3DRQ12QzGJXvVswvQ"
                }
            },
            {
                "state": "STARTED",
                "primary": false, // 从副本
                "node": "3bo9Z0krShyAK-t_F5Fo8A",
                "relocating_node": null,
                "shard": 1,  // 只需要检索`shard` 1
                "index": "my_index2",
                "allocation_id": {
                    "id": "NWILXOXcTGCXYHrgPJ6_-A"
                }
            }
        ]
    ]
}
下面的查询只会检索与routing key,"key1"和"key2"相关的shard
GET /my_index2/_search?routing=key1,key2
{
  "query": {
    "term": {
      "name": "n2"
    }
  }
}
其它
The default value used for _routing is the document’s _id.
因此在不自定义routing的情况下,形如
GET /my_index1/student/1
只会命中单个shard,效率也并不低。
参考资料
请我喝瓶饮料
