我有一个jsonb列,其不幸的情况是非常不可预测,在某些情况下,它的值可能是一个带有嵌套值的数组:
["UserMailer", "applicant_setup_3", ["5cbffeb7-8d5e-4b52-a475-3cf320b2cee9"]]有时,它会有类似的键值/值:
[{"reference_id": "5cbffeb7-8d5e-4b52-a475-3cf320b2cee9", "job_dictionary": ["StatusUpdater", "FollowTwitterUsersJob"]}]是否有一种方法可以编写一个查询,它只将整个列作为文本,并执行一个like来查看我是否能够在大文本块中找到uuid?我希望找到jsonb列中存在特定uuid字符串的所有记录。
查询不需要快速或高效。
发布于 2019-09-21 19:31:22
Postgres有针对jsonb的搜索操作符?,但这需要您递归地搜索json内容。
一种可能的方法,尽管不是非常有效的方法,可以对对象进行字符串化,并使用LIKE搜索它:
myjsonb::text LIKE '%"5cbffeb7-8d5e-4b52-a475-3cf320b2cee9"%'
myjsonb::text LIKE '%"' || myuuid || '"%'发布于 2019-09-22 02:19:05
?的问题在于它只考虑顶级键(包括数组元素),而不考虑值,而不考虑嵌套对象。
您似乎在寻找任何级别上的值、和数组元素(而不是键)。您可以在json(b)列的顶部搜索全文:
SELECT * FROM tbl
WHERE to_tsvector('simple', jsonb_column)
@@ tsquery '5cbffeb7-8d5e-4b52-a475-3cf320b2cee9';db<>fiddle https://dbfiddle.uk/?rdbms=postgres_12&fiddle=0184927f32db682a28c9a5667a290b7a
to_tsvector()在所有级别上提取值和数组元素--这正是您所需要的。
需要Postgres 10或更高版本。Postgres 11中的json(b)_to_tsvector()提供了更多的灵活性。
这对于具有非平凡大小的表很有吸引力,因为全文索引可以非常有效地支持它:
CREATE INDEX tbl_jsonb_column_fts_gin_idx ON tbl USING GIN (to_tsvector('simple', jsonb_column));我在示例中使用了'simple'文本搜索配置。您可能需要一个特定于语言的系统,比如'english'。当您只查找UUID字符串时并不重要,但是特定语言的词干可能会使索引变得更小一些.
相关信息:
当您只查找UUID时,可以使用自定义(IMMUTABLE)函数进一步优化,以便将UUID从JSON文档中提取为数组(uuid[]),并在其之上构建函数GIN索引。(但指数要小得多。)然后:
SELECT * FROM tbl
WHERE my_uuid_extractor(jsonb_column) @> '{5cbffeb7-8d5e-4b52-a475-3cf320b2cee9}';这样的函数可能很昂贵,但是对于存储和操作预先计算的值的函数索引来说并不重要。
https://stackoverflow.com/questions/58043258
复制相似问题