# F.21.树
F.21.1.定义F.21.2.运算符和函数F.21.3.索引F.21.4.实例F.21.5.转变F.21.6.作者
该模块实现了一种数据类型树
用于表示存储在层次树状结构中的数据标签。提供了广泛的设施,用于搜索标签树。
该模块被认为是“受信任的”,也就是说,它可以由拥有创造
当前数据库的权限。
# F.21.1.定义
A.标签是字母数字字符和下划线的序列(例如,在C语言环境中A-Za-z0-9_
允许)。标签长度必须小于256个字符。
例如:42
,个人服务
A.标签路径例如,由点分隔的零个或多个标签序列L1.L2.L3
,表示从层次树的根到特定节点的路径。标签路径的长度不能超过65535个标签。
例子:顶部国家。欧洲俄罗斯联邦
这个树
模块提供了几种数据类型:
树
存储标签路径。lquery
表示用于匹配的类似正则表达式的模式树
价值观一个简单的单词与路径中的标签匹配。星象(*
)匹配零个或多个标签。这些可以与点连接,形成必须与整个标签路径匹配的图案。例如:foo Match the exact label path foo *.foo.* Match any label path containing the label foo *.foo Match any label path whose last label is foo
星号和简单单词都可以量化,以限制它们可以匹配多少标签:
*{n} Match exactly n labels *{n,} Match at least n labels *{n,m} Match at least n but not more than m labels *{,m} Match at most m labels — same as *{0,m} foo{n,m} Match at least n but not more than m occurrences of foo foo{,} Match any number of occurrences of foo, including zero
在没有任何显式量词的情况下,星号的默认值是匹配任意数量的标签(即,
{,}
)而非星形项的默认值是只匹配一次(即,{1}
).有几个修饰符可以放在非星形的末尾
lquery
使其不只是精确匹配的项目:@ Match case-insensitively, for example a@ matches A * Match any label with this prefix, for example foo* matches foobar % Match initial underscore-separated words
行为
%
这有点复杂。它试图匹配单词,而不是整个标签。例如富吧%
比赛富巴兹
但不是富奥·巴巴兹
.如果与*
例如,前缀匹配分别应用于每个单词富吧%*
比赛foo1_bar2_baz
但不是foo1_br2_baz
.此外,您还可以编写几个可能已修改的非星形项,用
|
(或)匹配这些项目中的任何一项!
(不)在非明星组的开始,匹配任何与任何备选方案不匹配的标签。一个量词,如果有的话,放在小组的末尾;这意味着整个组中有一定数量的匹配项(也就是说,有一定数量的标签匹配或不匹配任何替代项)。下面是一个注释示例
lquery
:Top.*{0,2}.sport*@.!football|tennis{1,}.Russ*|Spain a. b. c. d. e.
此查询将匹配以下任何标签路径:
从标签开始
顶部
next之前有零到两个标签
以不区分大小写前缀开头的标签
运动
然后有一个或多个标签,但没有一个匹配
足球运动
也没有网球
然后以一个以
罗斯
还是完全匹配西班牙
.
ltxtquery
表示用于匹配的类似全文搜索的模式树
价值观一ltxtquery
值包含单词,可能带有修饰符@
,*
,%
最后;修饰语的含义与中的相同lquery
.单词可以与&
(以及),|
(或),!
(不是),以及括号。与lquery
是吗ltxtquery
匹配单词,而不考虑它们在标签路径中的位置。这里有一个例子
ltxtquery
:Europe & Russia*@ & !Transportation
这将匹配包含标签的路径
欧洲
以及任何以俄罗斯联邦
(不区分大小写),但不包括包含标签的路径运输
.这些单词在路径中的位置并不重要。还有,什么时候%
使用时,该单词可以与标签中任何下划线分隔的单词匹配,而不管其位置如何。注:
ltxtquery
允许符号之间使用空格,但树
和lquery
不要。
# F.21.2.运算符和函数
类型树
有常用的比较运算符=
, <>
, <
, >
, <=
, >=
.比较按树遍历的顺序排序,节点的子节点按标签文本排序。此外,中所示的专业操作员表F.13都有。
表F.13. 树
操作员
操作人员 描述 |
---|
树 @> 树 → 布尔值 左派论点是右派(或同等)的祖先吗? |
树 <@ 树 → 布尔值 左派论点是右派的后代吗? |
树 ~ lquery → 布尔值 lquery -是的。 LTREE公司 →→布尔值 做 LTREE公司 匹配L查询 -是吗? |
LTREE公司 -是吗? lquery[] →→布尔值 lquery[] -是吗? LTREE公司 →→布尔值 做 LTREE公司 匹配任何L查询 在阵列中? |
LTREE公司 -是的。 LTX查询 →→布尔值 ltxt查询 @ ltree → 布尔值 做 ltree 匹配ltxt查询 ? |
ltree || ltree → ltree 连接 ltree 路径。 |
ltree || 文本 → ltree 文本 || ltree → ltree 将文本转换为 ltree 并连接。 |
ltree[] @> ltree → 布尔值 ltree <@ ltree[] → 布尔值 数组是否包含的祖先 ltree ? |
ltree[] <@ ltree → 布尔值 ltree @> ltree[] → 布尔值 数组是否包含 ltree ? |
ltree[] ~ 查询 → 布尔值 查询 ~ ltree[] → 布尔值 数组是否包含任何路径匹配 查询 ? |
ltree[] ? 查询[] → 布尔值 查询[] ? ltree[] → 布尔值 做 ltree 数组包含任何匹配任何路径查询 ? |
ltree[] @ ltxt查询 → 布尔值 ltxt查询 @ ltree[] → 布尔值 数组是否包含任何路径匹配 ltxt查询 ? |
ltree[] ?@> ltree → ltree 返回第一个数组条目,它是 ltree , 或者空值 如果没有。 |
ltree[] ?<@ ltree → ltree 返回第一个数组条目,它是 ltree , 或者空值 如果没有。 |
ltree[] ?~ 查询 → ltree 返回匹配的第一个数组条目 查询 , 或者空值 如果没有。 |
ltree[] ?@ ltxt查询 → ltree 返回匹配的第一个数组条目 ltxt查询 , 或者空值 如果没有。 |
运营商<@
, @>
, @
和~
有类似物^<@
,^@>
,^@
,^~
,它们是相同的,只是它们不使用索引。这些仅用于测试目的。
可用功能显示在表 F.14.
表 F.14.ltree
职能
# F.21.3.索引
树
支持多种类型的索引,可以加速指定的运算符:
B-树索引
树
:<
,<=
,=
,>=
,>
要点索引结束
树
(基本操作
opclass):<
,<=
,=
,>=
,>
,@>
,<@
,@
,~
,?
基本操作
GiST opclass将一组路径标签近似为位图签名。它的可选整数参数西格伦
以字节为单位确定签名长度。默认签名长度为8字节。签名长度的有效值在1到2024字节之间。更长的签名会导致更精确的搜索(扫描更少的索引部分和更少的堆页),但代价是索引更大。创建默认签名长度为8字节的索引的示例:
CREATE INDEX path_gist_idx ON test USING GIST (path);
创建签名长度为100字节的索引的示例:
CREATE INDEX path_gist_idx ON test USING GIST (path gist_ltree_ops(siglen=100));
要点索引结束
ltree[]
(基本操作
opclass):ltree[]<@ltree
,ltree@>ltree[]
,@
,~
,?
基本操作
这个类的工作原理与基本操作
并将签名长度作为参数。的默认值西格伦
在里面基本操作
是28字节。创建默认签名长度为28字节的索引的示例:
CREATE INDEX path_gist_idx ON test USING GIST (array_path);
创建签名长度为100字节的索引的示例:
CREATE INDEX path_gist_idx ON test USING GIST (array_path gist__ltree_ops(siglen=100));
注意:此索引类型是有损的。
# F.21.4.范例
本例使用以下数据(也可在文件中找到contrib/ltree/ltreetest。sql
在源代码分发中):
CREATE TABLE test (path ltree);
INSERT INTO test VALUES ('Top');
INSERT INTO test VALUES ('Top.Science');
INSERT INTO test VALUES ('Top.Science.Astronomy');
INSERT INTO test VALUES ('Top.Science.Astronomy.Astrophysics');
INSERT INTO test VALUES ('Top.Science.Astronomy.Cosmology');
INSERT INTO test VALUES ('Top.Hobbies');
INSERT INTO test VALUES ('Top.Hobbies.Amateurs_Astronomy');
INSERT INTO test VALUES ('Top.Collections');
INSERT INTO test VALUES ('Top.Collections.Pictures');
INSERT INTO test VALUES ('Top.Collections.Pictures.Astronomy');
INSERT INTO test VALUES ('Top.Collections.Pictures.Astronomy.Stars');
INSERT INTO test VALUES ('Top.Collections.Pictures.Astronomy.Galaxies');
INSERT INTO test VALUES ('Top.Collections.Pictures.Astronomy.Astronauts');
CREATE INDEX path_gist_idx ON test USING GIST (path);
CREATE INDEX path_idx ON test USING BTREE (path);
现在,我们有了一张桌子测验
填充了描述如下所示层次结构的数据:
Top
/ | \
Science Hobbies Collections
/ | \
Astronomy Amateurs_Astronomy Pictures
/ \ |
Astrophysics Cosmology Astronomy
/ | \
Galaxies Stars Astronauts
我们可以这样做:
ltreetest=> SELECT path FROM test WHERE path <@ 'Top.Science';
path
### F.21.5. Transforms
Additional extensions are available that implement transforms for the `ltree` type for PL/Python. The extensions are called `ltree_plpythonu`, `ltree_plpython2u`, and `ltree_plpython3u` (see [Section 46.1](plpython-python23.html) for the PL/Python naming convention). If you install these transforms and specify them when creating a function, `ltree` values are mapped to Python lists. (The reverse is currently not supported, however.)
### Caution
It is strongly recommended that the transform extensions be installed in the same schema as `ltree`. Otherwise there are installation-time security hazards if a transform extension's schema contains objects defined by a hostile user.
### F.21.6. Authors
All work was done by Teodor Sigaev (`<[teodor@stack.net](mailto:teodor@stack.net)>`) and Oleg Bartunov (`<[oleg@sai.msu.su](mailto:oleg@sai.msu.su)>`). See [http://www.sai.msu.su/\~megera/postgres/gist/](http://www.sai.msu.su/~megera/postgres/gist/) for additional information. Authors would like to thank Eugeny Rodichev for helpful discussions. Comments and bug reports are welcome.