我的用户模型有jsonb列,其名称为raw
。它看起来像这样:
{"client"=>{"tokens"=>["asdasd"]}}
现在我想通过raw["client"]["tokens"]
中的令牌找到用户。我怎么能这样做?
答案 0 :(得分: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
UPDATE2:
另一种查询方式是:
raw @> '{"client": {"tokens": ["asdasd"]}}'
哪个应该能够在原始列上使用简单的GIN
索引(使用比上述表达式索引更多的空间)。
CREATE INDEX index_user_raw ON users USING GIN (raw)
再次:详细信息请参阅上面的JSON INDEXING链接。并使用Query Visualizer查看差异。我喜欢http://tatiyants.com/pev