我想在表格中的JSON对象中进行文本搜索。
我有一个名为Audio的表,结构如下:
id| keyword | transcript | user_id | company_id | client_id
-----------------------------------------------------------
这是transcript
:
{"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"}
]
},
...
}
我要做的是在“单词”中的“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
我很想知道我的查询问题是什么,以及是否有更有效的方法来执行此操作。
答案 0 :(得分:1)
问题在于,您一方面在表Audio
与另一方面info_data
和info_item
之间进行笛卡尔联接(后两者之间存在隐式横向连接) )这里:
FROM Audio, info_data idata, json_array_elements(idata.info) AS info_item
您可以通过将Audio.id
添加到CTE然后添加WHERE Audio.id = info_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”之外,英语中的单词很少以同样的结尾,我已经冒昧地删除了它。