我有一个 postgres 表(用户),其中有一个 JSONb 列(元数据)。目前,我正在通过电子邮件搜索用户,它工作得很好,只是电子邮件必须完全匹配。
因此,如果用户有电子邮件bob@smith.com并且我User.by_email("bob@smith.com")这样做,效果会很好。但我想User.by_email("@smith.com")返回所有具有匹配电子邮件的用户。
在我的user.rb模型中,我有以下内容:
scope :by_email, ->(email) { where("metadata @> ?", { session: { Primary: { Email: email.to_s.downcase} } }.to_json) }
Run Code Online (Sandbox Code Playgroud)
这就是允许User.by_email(email)工作的原因。如何修改它以查找具有与传入字符串匹配的电子邮件的所有用户?
第二部分是我也希望能够按用户名进行搜索。
这将通过以下方式完成scope :by_name, ->(name) { where("metadata @> ?", { session: { Primary: { FullName: name.to_s} } }.to_json) }
我怎样才能同时做这两件事?如果这只是简单的 activerecord 我知道我可以这样做:
User.where("full_name LIKE ? OR email LIKE", "%#{search}%","%#{search}%")
Run Code Online (Sandbox Code Playgroud)
如何使用 JSONb 列执行此操作?
我有一个 Postgres 9.4.4 数据库,其中包含 170 万条记录,以下信息存储在名为 的表中调用的 JSONB 列data中accounts:
data: {
"lastUpdatedTime": "2016-12-26T12:09:43.901Z",
"UID": "2c5bb7fd-1a00-4988-8d92-ffaa52ebc20d",
"data": {
"country": "UK",
"verified_at": "2017-01-01T23:49:10.217Z"
}
}
Run Code Online (Sandbox Code Playgroud)
数据格式无法更改,因为这是旧信息。
我需要获取国家/地区所在的所有帐户UK,该verified_at值不为空并且该lastUpdatedTime值大于某个给定值。
到目前为止,我有以下查询:
SELECT * FROM "accounts"
WHERE (data @> '{ "data": { "country": "UK" } }')
AND (data->'data' ? 'verified_at')
AND ((data->'data' ->> 'verified_at') is not null)
AND (data ->>'lastUpdatedTime' > '2016-02-28T05:49:08.511846')
ORDER BY data ->>'lastUpdatedTime' LIMIT 100 OFFSET 0;
Run Code Online (Sandbox Code Playgroud)
以及以下指标:
"accounts_idxgin" gin (data)
"accounts_idxgin_on_data" gin …Run Code Online (Sandbox Code Playgroud) 谷歌搜索,发现了很多潜在的解决方案来正确处理它,最终得到了以下有效的解决方案
def item_params
load_params = params.require(:item).permit(
:title,
:content
)
load_params[:meta] = params[:item][:meta] if params[:item][:meta]
load_params.permit!
end
Run Code Online (Sandbox Code Playgroud)
使用这样的有效负载(查看控制台):
{
"item" => {
"title"=>"abc",
"meta"=>{
"fontcolor"=>"xyz",
}
}
}
Run Code Online (Sandbox Code Playgroud)
日志仍然显示该字段是不允许的:
Unpermitted parameter: :meta
Run Code Online (Sandbox Code Playgroud)
不阻塞,它确实传递这些参数并正确保存,即使有警告也是如此。
不在相关列上使用序列化或任何序列化器,因为没有它它可以按预期工作(与大量谈论 json 列和序列化的帖子交谈,现在似乎不像以前那样需要)
这个解决方案在我这边不起作用,同样的警告,但元参数是否被阻止:
def item_params
meta_keys = params[:item][:meta].keys
params.require(:item).permit(:title, meta: meta_keys)
end
Run Code Online (Sandbox Code Playgroud)
因为这看起来有点随机,所以我对最终决定使用什么以及如何使用感到非常不舒服;如果有任何有信心的建议,非常感谢
我的目的是jsonb使用jsonb_set具有多个键值对的对象来更新当前为空的列。更新命令成功执行,但它没有更新任何内容,该列仍然为空。我正在尝试以下查询。
UPDATE tab
set value = jsonb_set(value, '{}', '{"a" : 100, "b" : [100, 200]}'::jsonb)
where id = 100;
Run Code Online (Sandbox Code Playgroud)
有什么解决办法吗?
我正在尝试使用 jsonb_set 更新数据库中的一系列 json 对象。我可以使用一个查询来使用字符串值更新对象,但是我似乎无法使用当前值来更新它。
UPDATE entity
SET properties = jsonb_set(properties, '{c_number}', concat('0', properties->>'c_number'))
WHERE type = 1 and length(properties->>'c_number') = 7
Run Code Online (Sandbox Code Playgroud)
上面的内容在当前格式下不起作用,我认为问题出在properties->>'c_number'jsonb_set 内部。有没有办法可以访问当前值并简单地添加前导 0?
我正在尝试查找哪些 jsonb 键是我所在领域中最受欢迎的键data。我能够通过以下查询获取所有键的名称:
select jsonb_object_keys(data) as key
from client
group by key;
Run Code Online (Sandbox Code Playgroud)
当我尝试像平常一样添加计数时:
select jsonb_object_keys(data) as key, count(jsonb_object_keys(data))
from client
group by key;
Run Code Online (Sandbox Code Playgroud)
我收到此错误:
ERROR: aggregate function calls cannot contain set-returning function calls
Run Code Online (Sandbox Code Playgroud)
有没有办法计算 jsonb 对象的不同键?
样本数据:
data
{"a": "xyz"}
{"b": "assa", "c": "134323"}
{"c": "123"}
{"c": "12324", "a": "xysaz"}
Run Code Online (Sandbox Code Playgroud)
期望的输出:
key count(key)
a 2
b 1
c 3
Run Code Online (Sandbox Code Playgroud) 我jsonb在 Postgres 表中有这样的结构:{ "res": [123, 223] }并且我想将值推入res-array 中。我不知道数组上有多少个值以及jsonb_insert对位置进行操作,所以我尝试使用-1位置:
select jsonb_insert( '{"res": [123, 223]}', '{res,-1}', '333');
jsonb_insert
--------------------------
{"res": [123, 333, 223]}
Run Code Online (Sandbox Code Playgroud)
这是行不通的。如何将新值推入数组末尾?
我正在使用 Postgres 9.6
我在 Postgres(版本 10)中有一个表,其中包含一个可为空的 jsonb 列:
CREATE TABLE j_play (
id serial PRIMARY KEY,
created_ts TIMESTAMPTZ,
data JSONB
);
Run Code Online (Sandbox Code Playgroud)
可能最初插入的记录没有 json 数据,因此该列将为空。
| id | created_ts | data
| 1 | 2020-09-11 18:18:37.47755+00 | [null]
Run Code Online (Sandbox Code Playgroud)
我想更新此记录,以便如果 'null' 添加一个 json 对象,并且如果一个 json 对象已经存在,则对其进行修改。
UPDATE j_play SET data = '{"a": "12345"}'
| id | created_ts | data
| 1 | 2020-09-11 18:18:37.47755+00 | {"a": "12345"}
UPDATE j_play SET data = '{"b": "54321"}' -- This is obviously bogus but the intention is to amend …Run Code Online (Sandbox Code Playgroud) 我有以下测试表:
CREATE TABLE user (
id UUID NOT NULL PRIMARY KEY DEFAULT uuid_generate_v4(),
name VARCHAR(100),
address jsonb
)
Run Code Online (Sandbox Code Playgroud)
我想要做的是将此表加载到实体中
public class Buddy{
@Id
private UUID id;
private String name;
private Address address;
//getter and setter
}
Run Code Online (Sandbox Code Playgroud)
地址是这样的
public class Address {
@JsonProperty("name")
public String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Run Code Online (Sandbox Code Playgroud)
我不清楚如何将我的 json 字符串转换为 java Pojo?是否可以这样做,或者超出范围?
在我的 PostgreSQL 11.11 中,我有一列jsonb保存如下对象:
{
"dynamicFields":[
{
"name":"200",
"hidden":false,
"subfields":[
{
"name":"a",
"value":"Subfield a"
},
{
"name":"b",
"value":"Subfield b"
}
]
}
]
}
Run Code Online (Sandbox Code Playgroud)
dynamicFields是一个数组,subfields也是一个数组,当我点击这样的选择时遇到性能问题:
select *
from my_table a
cross join lateral jsonb_array_elements(jsonb_column -> 'dynamicFields') df
cross join lateral jsonb_array_elements(df -> 'subfields') sf
where df ->> 'name' = '200' and sf ->> 'name' = 'a'
Run Code Online (Sandbox Code Playgroud)
性能问题主要存在于subfield. 我已经添加了这样的索引:
CREATE INDEX idx_my_index ON my_table USING gin ((marc->'dynamicFields') jsonb_path_ops);
Run Code Online (Sandbox Code Playgroud)
如何为subfields内部添加索引dynamicFields?
上面的查询只是一个示例,我在与数据库中其他表的联接中经常使用它。而且我也认识 …
jsonb ×10
postgresql ×10
sql ×3
json ×2
sql-update ×2
activerecord ×1
indexing ×1
ruby ×1
spring ×1
spring-data ×1