在 postgres 中查询文本数组

Posted

技术标签:

【中文标题】在 postgres 中查询文本数组【英文标题】:Querying array of text in postgres 【发布时间】:2019-02-01 23:55:59 【问题描述】:

我有一个要存储在 Postgres 中的数组类型。我的主要用例之一是查看是否有任何记录具有包含字符串的数组。

例如。

| A | ["NY", "Paris", "Milan"] |
| B | ["Paris", "NY"]          |
| C | []                       |
| D | ["Milan"]                |

数组中是否存在带有Paris 的行?数组中有哪些行有Milan?等等。

关于如何存储该列,我有 2 个选项。我可以将其设为 text[] 类型或将其转换为 json 为 "cities": ["NY", "Paris", "Milan"] 然后存储为 JSONB 字段

但是,我不确定什么可以让我对我的用例进行最快的查询。有没有明显更好的方法来做到这一点?我是否通过选择一个而不是另一个来束缚自己?如果我选择其中一个,那么如何查询数据库?

【问题讨论】:

【参考方案1】:

我注意到最好查询 JSONB,如果它是一个简单的键值存储。 例如,您想在不确定列(键)是什么的行上存储任意信息。 info = "a":"apple", "b":"ball"

对于像您这样的用例,最好使用简单的表来设计数据库,这样您就可以利用 JOINS 和索引来发挥自己的优势。

您可以像这样重组表格:

位置

id | name
----------
1  | Paris
2  | NY
3  | Milan 

其他表(位置表上有外键)

user | location_id
--------------------
A    | 1
A    | 3
B    | 2

使用这组表,可以很容易地使用 JOINS 查询所有位置为 paris 的用户。

【讨论】:

【参考方案2】:

由于您似乎存储的是简单的值列表,我建议使用 datataype Array 而不是 JSON,它更适合更复杂的情况(嵌套数据结构、关联数组等)。

要检查数组中任意位置的元素值,可以使用数组函数ANY()

这是一个查询,它将返回存储在列cities 中的数组包含'Paris' 的所有记录:

SELECT t.* FROM mytable t WHERE 'Paris' = ANY(t.cities);

产量:

id  cities
---------------------------
A   ["NY","Paris","Milan"]
B   ["Paris","NY"]

Demo on DB Fiddle

更多信息:

Postgres Arrays Documentation Postgres Arrays Tutorial

【讨论】:

以上是关于在 postgres 中查询文本数组的主要内容,如果未能解决你的问题,请参考以下文章

在 Postgres JSON 数组中查询

在 postgres 选择中,将列子查询作为数组返回?

Postgres:计算子查询中的唯一数组条目

LIKE查询的最佳Postgres文本索引?

从 Postgres 13 开始,哈希索引是不是最适合精确文本匹配查询?

使用 objection.js 或 knex.js 在 postgres 中的字符串列的 json 数组中查询