lr_*_*tim 3 python sql postgresql ltree sqlmodel
我的数据库中有一些资源继承到它们的子资源。当我查询资源时,我还需要能够获取继承的资源。我有一个名为path我计划使用的字段。始终path包含与我们当前正在处理的资源相关的所有资源的完整路径。
例子:
+-----------------------------------------+
| id | res_id | path |
|-----------------------------------------|
| 1 | res_1 | res_1 |
| 2 | res_1.1 | res_1.res_1.1 |
| 3 | res_1.2 | res_1.res_1.2 |
| 4 | res_1.1.1 | res_1.res_1.1.res_1.1.1|
+-----------------------------------------+
Run Code Online (Sandbox Code Playgroud)
如果我查询res_1.1,我还必须获取 ,res_1因为它是 的父级res_1.1。如果我得到res_1.1.1,我还必须得到第 1 行和第 2 行,因为它们包含在 的路径中res_1.1.1。希望得到一些关于如何使用 Postgres 执行此操作的建议。如果这是重要信息,我也用来sqlmodel编写查询。
编辑。对于含糊的介绍,我深表歉意,该参数path已经是sqlalchemy Ltree字段。我希望这能让事情变得更简单一些?
ltree事实证明您正在使用附加模块ltree。点 ( .) 是明确的分隔符。假设path是类型ltree(您还没有澄清)可以简化任务。有专门的操作员,例如:
\n\n\n
ltree @> ltree\xe2\x86\x92boolean左参数是右参数的祖先(或等于)吗?
\n
所以:
\nSELECT t.*\nFROM tbl_ltree t1 \nJOIN tbl_ltree t ON t.path @> t1.path\nWHERE t1.res_id = \'res_1_1_1\'; -- your search term here\nRun Code Online (Sandbox Code Playgroud)\nltree还提供了 GiST 索引的运算符类:
CREATE INDEX tbl_ltree_path_gist_idx ON tbl USING GIST (path);\nRun Code Online (Sandbox Code Playgroud)\n..可以被上面的查询使用。另外,您还会在 上拥有另一个 B 树索引res_id。
res_id是完全多余的,可以忽略甚至丢弃。我们可以使用另一个 ltree 运算符path来代替:
\n\n\n\n
ltree ~ lquery\xe2\x86\x92booleanltree 与 lquery 匹配吗?
\n
CREATE INDEX tbl_ltree_path_gist_idx ON tbl USING GIST (path);\nRun Code Online (Sandbox Code Playgroud)\ndb<>在这里摆弄
\n只需要 GiST 索引。
\ntext在使用text而不是ltree(您还没有澄清)时,这是多种方法之一:
SELECT *\nFROM tbl_ltree \nWHERE path @> (SELECT path FROM tbl_ltree WHERE path ~ \'*.res_1_1_1\'::lquery);\nRun Code Online (Sandbox Code Playgroud)\ndb<>在这里摆弄
\n子查询t1分为path其构建块。然后加入到另一个实例tbl_txt。