使用 jsonb (PostgreSQL),如何检索保存为数组的具有特定值的项目?

Using jsonb (PostgreSQL), how do I retrieve items with a certain value that's saved as an array?

我正在尝试查找某个类别中的所有食谱,其中 key/value 数据记录在 PostgreSQL 的 jsonb 列中(并将值保存为数组)。

例如,假设我在 "recipes" table 中有 "data" 作为我的 jsonb 列,并且我有如下三个条目:

"Recipe 1" contains a "data" with key/value of: "category_ids"=>[123, 4059]
"Recipe 2" contains a "data" with key/value of: "category_ids"=>[405, 543]
"Recipe 3" contains a "data" with key/value of: "category_ids"=>[567, 982]

我只想检索包含“405”类别 ID 值的项目(即,仅上面的方法 2)

这是我目前在 Rails 上使用 Ruby 查询 PostgreSQL 数据库的结果:

Recipe.where("(data ->> 'category_ids') LIKE '%405%'")

但是,这会同时检索 "Recipe 1" 和 "Recipe 2",因为它们都包含“405”文本。

我应该使用什么查询来正确检索仅具有“405”类别 ID 的食谱?

您可以使用 unnest function 可用。更多细节可以在这里查看:Postgresql Functions & Operators.

您需要 ANY 功能。像

select * from t where '405' = any (
  ARRAY(
    SELECT e::text FROM json_array_elements(data->'category_ids') e
  )
);

select * from t where '405' = any (
  ARRAY(
    SELECT e::text FROM jsonb_array_elements(data->'category_ids') e
  )
);

如果你的类型是jsonb(postgres 9.3以上版本)

http://sqlfiddle.com/#!15/1a895/1

您也可以直接使用 IN 和 json_array_elements:

Recipe.where("'405' IN (SELECT json_array_elements(data->'category_ids')::text)")

如果你的列是 jsonb 列,你也可以这样做:

Recipe.where("'405' IN (SELECT jsonb_array_elements(data->'category_ids')::text)")