1 前言
在工作中,我们经常遇到父子结构的数据, 比如省市县, 部门人员, 数据字典, 菜单结构等.
我们在设计表结构时, 一定要设计好, 否则查询会比较耗时.
通常设计父子结构的表时有如下方案:
左右值法
在节点里维护左右值, 查询子孙节点比较方便, 但是维护比较麻烦, 数据也不直观
parentId
每一行数据保存父亲节点的Id, 这样查直属下级比较方便, 但是查询子孙节点, 递归很慢
parentId+path
在第2点基础上加上path, path是所有祖先节点的id,用逗号分隔.
比如有如下结构:
在这里插入图片描述
那么"三级 2-1-1"的path就会是"2,2-1,2-1-1",
你要统计"一级2"所有子孙节点个数时, 你或许会这么做
在用MySQL时: select count(1) from tablename where path like ‘2,%’
在用ES时, 你可能
GET tree/_search
{ "query": {
"prefix" : { "path" : "2," }
}
}
1
2
3
4
5
但数据量大时, MySQL的like和ES的prefix会比较慢.
优化parentId+path
在ES里, 将path设置为Nested类型, 它包含id,level这2个子字段
#这里用ancestorId(祖先ID)表示path的意思
"ancestorId":{
"type":"nested",
"properties": {
"id": { "type": "keyword" },
"level": { "type": "keyword" }
}
}
1
2
3
4
5
6
7
8
那"三级 2-1-1"的ancestorId值为:
[
{
"level":1,
"id":"2"
},
{
"level":2,
"id":"2-1"
},
{
"level":3,
"id":"2-1-1"
}
]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2 验证想法