JSONB 中的 Postgres 搜索
Postgres search in JSONB
一行中的 custom_fields 字段如下所示:
[
{
"value":"Test Name",
"display_name":"Name",
"servicio_tags":[
"person-name"
]
},
{
"value":"",
"display_name":"Telefonnummer",
"servicio_tags":[
"phone"
]
},
{
"value":"test@test.net",
"display_name":"E-Mail",
"servicio_tags":[
"e-mail"
]
},
{
"value":"Sonnberg 170",
"display_name":"Adresse",
"servicio_tags":[
"address"
]
},
{
"value":"1/",
"display_name":"Personen Anzahl",
"servicio_tags":[
"person-number-info"
]
},
{
"value":"",
"display_name":"Notiz",
"servicio_tags":[
"trace"
]
},
{
"value":"A la Carte",
"display_name":"Typ",
"servicio_tags":[
"price-type"
]
},
{
"value":"Montag, 11. Mai 2020 19:30",
"display_name":"Anreise",
"servicio_tags":[
"arrival"
]
},
{
"value":"Montag, 11. Mai 2020 20:30",
"display_name":"Abreise",
"servicio_tags":[
"departure"
]
},
{
"value":"2020-05-11 19:30",
"display_name":"Ankunft bei Reservierung",
"servicio_tags":[
"arrival",
"hidden"
]
},
{
"value":"2020-05-11 20:30",
"display_name":"Abfahrt bei Reservierung",
"servicio_tags":[
"departure",
"hidden"
]
}
]
我想通过使用 searchTerm 搜索包含 servicio_tags":["person-name"]
或 servicio_tags":["full-name"]
.
的对象的 value
键的值来查询此数据库
所以如果 searchTerm 是 a
它应该返回这一行,因为 JSON
中的对象
{
"value":"Anton Hoerl Jun.",
"display_name":"Name",
"servicio_tags":[
"person-name"
]
},
符合这个标准。
我的尝试:
const fullNameString = '%{"value": "' + searchTerm + '", "display_name": "Name", "servicio_tags": ["full-name"]}%';
const personNameString = '%{"value": "' + searchTerm + '", "display_name": "Name",
"servicio_tags": ["person-name"]}%';
const result = await this.db.query(
`SELECT *
FROM guest_group
AND custom_fields::text like
OR custom_fields::text like LIMIT 5`, [customerId, fullNameString, personNameString]);
这个查询没有给我想要的结果,因为如果 seachTerm 与键值的值完全一样,它只有 returns 行。如果 value 键的值仅包含 searchTerm,我也希望它 returns 该行。
感谢您的帮助。
您需要取消嵌套数组并比较各个值:
select g.*
from guest_group g
where exists (select *
from jsonb_array_elements(g.custom_fields) as f(element)
where f.element ->> 'value' ilike 'a%');
请注意,我使用 ilike
进行不区分大小写的比较。
一行中的 custom_fields 字段如下所示:
[
{
"value":"Test Name",
"display_name":"Name",
"servicio_tags":[
"person-name"
]
},
{
"value":"",
"display_name":"Telefonnummer",
"servicio_tags":[
"phone"
]
},
{
"value":"test@test.net",
"display_name":"E-Mail",
"servicio_tags":[
"e-mail"
]
},
{
"value":"Sonnberg 170",
"display_name":"Adresse",
"servicio_tags":[
"address"
]
},
{
"value":"1/",
"display_name":"Personen Anzahl",
"servicio_tags":[
"person-number-info"
]
},
{
"value":"",
"display_name":"Notiz",
"servicio_tags":[
"trace"
]
},
{
"value":"A la Carte",
"display_name":"Typ",
"servicio_tags":[
"price-type"
]
},
{
"value":"Montag, 11. Mai 2020 19:30",
"display_name":"Anreise",
"servicio_tags":[
"arrival"
]
},
{
"value":"Montag, 11. Mai 2020 20:30",
"display_name":"Abreise",
"servicio_tags":[
"departure"
]
},
{
"value":"2020-05-11 19:30",
"display_name":"Ankunft bei Reservierung",
"servicio_tags":[
"arrival",
"hidden"
]
},
{
"value":"2020-05-11 20:30",
"display_name":"Abfahrt bei Reservierung",
"servicio_tags":[
"departure",
"hidden"
]
}
]
我想通过使用 searchTerm 搜索包含 servicio_tags":["person-name"]
或 servicio_tags":["full-name"]
.
value
键的值来查询此数据库
所以如果 searchTerm 是 a
它应该返回这一行,因为 JSON
{
"value":"Anton Hoerl Jun.",
"display_name":"Name",
"servicio_tags":[
"person-name"
]
},
符合这个标准。
我的尝试:
const fullNameString = '%{"value": "' + searchTerm + '", "display_name": "Name", "servicio_tags": ["full-name"]}%';
const personNameString = '%{"value": "' + searchTerm + '", "display_name": "Name",
"servicio_tags": ["person-name"]}%';
const result = await this.db.query(
`SELECT *
FROM guest_group
AND custom_fields::text like
OR custom_fields::text like LIMIT 5`, [customerId, fullNameString, personNameString]);
这个查询没有给我想要的结果,因为如果 seachTerm 与键值的值完全一样,它只有 returns 行。如果 value 键的值仅包含 searchTerm,我也希望它 returns 该行。
感谢您的帮助。
您需要取消嵌套数组并比较各个值:
select g.*
from guest_group g
where exists (select *
from jsonb_array_elements(g.custom_fields) as f(element)
where f.element ->> 'value' ilike 'a%');
请注意,我使用 ilike
进行不区分大小写的比较。