查询嵌套JSON时出现未知重复项
我想在表中的JSON对象中进行文本搜索 我有一个名为Audio的表格,其结构如下:查询嵌套JSON时出现未知重复项,json,postgresql,jsonb,Json,Postgresql,Jsonb,我想在表中的JSON对象中进行文本搜索 我有一个名为Audio的表格,其结构如下: id| keyword | transcript | user_id | company_id | client_id ----------------------------------------------------------- 这是转录本的JSON数据结构: {"transcript": [ {"duration": 2390.0, "interval": [140.0, 253
id| keyword | transcript | user_id | company_id | client_id
-----------------------------------------------------------
这是转录本的JSON数据结构:
{"transcript": [
{"duration": 2390.0,
"interval": [140.0, 2530.0],
"speaker": "Speaker_2",
"words": [
{"p": 0, "s": 0, "e": 320, "c": 0.545, "w": "This"},
{"p": 1, "s": 320, "e": 620, "c": 0.825, "w": "call"},
{"p": 2, "s": 620, "e": 780, "c": 0.909, "w": "is"},
{"p": 3, "s": 780, "e": 1010, "c": 0.853, "w": "being"},
{"p": 4, "s": 1010, "e": 1250, "c": 0.814, "w": "recorded"}
]
},
{"duration": 4360.0,
"interval": [3280.0, 7640.0],
"speaker": "Speaker_1",
"words": [
{"p": 5, "s": 5000, "e": 5020, "c": 0.079, "w": "as"},
{"p": 6, "s": 5020, "e": 5100, "c": 0.238, "w": "a"},
{"p": 7, "s": 5100, "e": 5409, "c": 0.689, "w": "group"},
{"p": 8, "s": 5410, "e": 5590, "c": 0.802, "w": "called"},
{"p": 9, "s": 5590, "e": 5870, "c": 0.834, "w": "tricks"}
]
},
...
}
我想做的是在“words”中的“w”字段中进行文本搜索。这是我尝试运行的查询:
WITH info_data AS (
SELECT transcript_info->'words' AS info
FROM Audio t, json_array_elements(transcript->'transcript') AS transcript_info)
SELECT info_item->>'w', id
FROM Audio, info_data idata, json_array_elements(idata.info) AS info_item
WHERE info_item->>'w' ilike '%this';
现在我只有四列数据,第五列为空。总共有五列。但是,我得到了以下结果,其中即使没有数据的列也会产生一个输出:
?column? | id
----------+----
This | 2
This | 5
This | 1
This | 3
This | 4
This | 2
This | 5
我很想知道我的问题是什么,以及是否有更有效的方法 问题在于,您一方面在表音频
与信息数据
和信息项
之间进行笛卡尔连接(后两者之间存在隐式横向连接):
您可以通过将Audio.id
添加到CTE,然后添加WHERE Audio.id=info\u data.id
来解决此问题
这是否是最有效的解决方案值得怀疑(CTE很少如此)。如果您只想在成绩单中找到“this”一词所在的行,那么您最好这样做:
SELECT DISTINCT id
FROM (
SELECT id, transcript_info->'words' AS info
FROM Audio, json_array_elements(transcript->'transcript') AS transcript_info) AS t,
json_array_elements(info) AS words
WHERE words->>'w' ILIKE 'this';
请注意,模式字符串中的%
效率非常低。由于英语中除了“this”之外几乎没有其他单词以相同结尾,我冒昧地将其删除。非常感谢!在过去的几个小时里,我一直在挣扎。这是一个更好的解决方案,我一直在寻找!您知道如何在sqlalchemy中解决隐式横向连接问题吗?我试图将您的建议转换为sqlalchemy查询,但遇到了完全相同的问题。在这里看到更多:我不能在这里帮助你,因为我不懂炼金术。但是,surefire解决方案是将上述查询包装在视图中,省去WHERE
子句,并根据需要向选择列表中添加尽可能多的其他列(words
)。在SQLAlchemy中,您只需从视图中选择并附加WHERE
子句即可。这是一种适用于所有数据库框架(Hibernate、rails等)的可靠方法:将所有查询复杂性留在数据库中,在框架中完成简单的工作。
SELECT DISTINCT id
FROM (
SELECT id, transcript_info->'words' AS info
FROM Audio, json_array_elements(transcript->'transcript') AS transcript_info) AS t,
json_array_elements(info) AS words
WHERE words->>'w' ILIKE 'this';