我们有一个数据表,如下所示:
CREATE TABLE objects (
id BIGSERIAL NOT NULL,
typeid BIGINT NOT NULL,
fullobject JSON,
PRIMARY KEY (id),
...
);
和
CREATE TABLE types (
id BIGSERIAL NOT NULL,
type VARCHAR(255),
PRIMARY KEY (id),
...
);
在objects.fullobject列中的是用户和组织的JSON数据,如:
// id: 1
{
...
"type":"1", // user
"orgs":[
{"id":"2", "position":"foo"},
{"id":"2", "position":"bar"},
{"id":"3", "position":"foo"},
]
}
// id: 2
{
...
"type":"2", // org
"name":"Org 1"
}
// id: 3
{
...
"type":"2", // org
"name":"Org 2"
}
问题是,如果我想根据组织名称找到用户,我该如何进行加入?
我不确定是否可以在用户内的组织数据上创建正确的索引。
我能想到的两个解决方案是:
然后查询如下:
SELECT * from objects user
INNER JOIN types usertype ON usertype.id = user.typeid
INNER JOIN objects org ON json_extract_path(user.fullobject, 'searchableOrg') LIKE '%|' || org.id || '|%'
INNER JOIN types usertype ON usertype.id = user.typeid
WHERE json_extract_path(org.fullobject, 'name') LIKE '%whatever%'
AND usertype.type = 'user'
AND orgtype.type = 'org'
这里我可以在json_extract_path(user.fullobject,' searchableOrg')和json_extract_path(org.fullobject,' name')上建立索引。
但是,如果我们向用户的组织成员身份添加诸如开始日期或结束日期之类的内容,并且需要进一步过滤此加入,则此功能无效。
我还没有看过触发器,但希望查询类似于:
SELECT * from objects user
INNER JOIN userorgtable userorg ON user.id = userorg.userid
INNER JOIN types usertype ON usertype.id = user.typeid
INNER JOIN objects org ON userorg.orgid = org.id
INNER JOIN types orgtype ON orgtype.id = org.typeid
WHERE json_extract_path(org.fullobject, 'name') LIKE '%whatever%'
AND usertype.type = 'user'
AND orgtype.type = 'org'
在这种情况下,如果我们需要向连接添加更多属性(例如开始日期和结束日期),我们可以将它们放在userorgtable中并添加条件,如:
AND userorg.startdate < CURRENT_DATE()
还有其他选择吗?也许使用更多的Postgres JSON函数?
提前致谢