【问题标题】:Search through jsonb column in ActiveRecord在 ActiveRecord 中搜索 jsonb 列
【发布时间】:2017-07-11 19:26:50
【问题描述】:

我的用户模型有名称为raw 的 jsonb 列。它看起来像这样:

{"client"=>{"tokens"=>["asdasd"]}}

现在我想通过raw["client"]["tokens"] 中的令牌查找用户。我该怎么做?

【问题讨论】:

  • 试试User.where("raw->'client'->'tokens' = ?", 'your token here')
  • 这可能与您要查找的内容有关 stackoverflow.com/questions/22667401/…
  • 如果你需要从tokens数组中搜索一个token,你必须使用@>:User.find_by("raw->'client'->'tokens' @> ?", ['token'].to_json)

标签: sql ruby-on-rails ruby postgresql


【解决方案1】:

我通常首先在 SQL 控制台中制作此类查询,然后将其转换为 ActiveRecord。

您可以在 Postgres 中导航哈希键。查询

SELECT
  raw #> '{client,tokens}'
FROM users

将从该路径仅返回 tokens 数组。现在我们需要检查它是否包含我们正在寻找的值。查询

SELECT
  raw #> '{client,tokens}' ? 'asdasd'
FROM users

将为具有匹配令牌的行选择t。现在您可以将其移至WHERE 部分:

SELECT
*
FROM users
WHERE  raw #> '{client,tokens}' ? 'asdasd'

如果这选择了您所期望的,那么您可以将其转换为 AR:

User.where("config #> '{client, tokens}' ? :token", token: 'asdasd')

请注意,我不能使用? 进行参数替换,而是使用:token。另请注意,这只适用于 JSONB (Postgres 9.4+ https://www.postgresql.org/docs/9.4/static/functions-json.html#FUNCTIONS-JSONB-OP-TABLE)

更新:

你应该(tm)(我没有测试过这个)相处:

CREATE INDEX index_tokens ON users USING GIN ((raw #> '{client, tokens}'));

详情请见https://www.postgresql.org/docs/9.6/static/datatype-json.html#JSON-INDEXING

更新2:

另一种查询方式是:

raw @> '{"client": {"tokens": ["asdasd"]}}'   

应该能够在原始列上使用简单的GIN 索引(它使用的空间比上面描述的表达式索引更多)。

CREATE INDEX index_user_raw ON users USING GIN (raw)

再次:详细信息请参阅上面的 JSON 索引链接。并使用查询可视化器查看差异。我喜欢http://tatiyants.com/pev

【讨论】:

  • 应该为这样的where定义什么索引?
猜你喜欢
  • 1970-01-01
  • 2021-11-04
  • 1970-01-01
  • 1970-01-01
  • 2021-09-27
  • 1970-01-01
  • 2015-08-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多