我有一个带有JSOB字段的Postgres表。
身体场的内容示例
{
"name": "example name",
"text": "example text",
"story":
{
"id":"UUID1"
},
"reference":
{
"type":"URI",
"content":
{
"id":"UUID2"
}
}
}我需要通过身份证找到文件,但它们可以在任何地方。
到目前为止我发现的唯一一件事
@Repository
public interface Repository extends JpaRepository<EntityWithJsonbField, String>{
...
Query(value="SELECT * FROM table_with_jsonb_field WHERE body ->> 'id' = :id ", nativeQuery = true)
List<EntityWithJsonbField> findAllWithId(@Param("id")String id);
...
}但是它只通过文档根目录中的id进行搜索。
也尝试了'$..id‘(JSON路径),而不是'id’,没有运气。
有可能吗?
PS以后,我需要更新找到的内容。因此,欢迎与相关文档的任何链接。:)
更新:,感谢a_horse_with_no_name,它现在开始工作了!
@Repository
public interface Repository extends JpaRepository<EntityWithJsonbField, String>{
...
Query(value="SELECT * FROM content_type WHERE body @@ cast(concat('$.**.id == \"',:id,'\"') as jsonpath)", nativeQuery = true)
List<EntityWithJsonbField> findAllWithId(@Param("id")String id);
...
}发布于 2022-07-25 18:03:14
使用普通SQL,可以这样做:
select *
from the_table
where jsonb_field @@ '$.**.id == "UUID2"';表达式$.**.id递归地遍历所有对象键,并将键id与值UUID2匹配。
但是,该表达式的比较值不能作为参数直接传递。因此,您需要通过传递(JPA)参数来连接在SQL中创建字符串,然后将该字符串转换为jsonpath。
"select from the_table " +
"where jsonb_field @@ concat('$.**.id == \"',:id,'\"')::jsonpath"如果您的混淆层阻塞了::,您可以使用:
"where jsonb_field @@ cast(concat('$.**.id == \"',:id,'\"') as jsonpath)"我只用普通的JDBC来测试这一点,不是用JPA,而是因为:id不包含在一个string中(只包含在Java中),所以这应该适用于JPA。
另一种选择是使用jsonb_path_exists(),如果参数应该传递到JSON路径表达式中,则使用起来更容易:
"select from the_table " +
"where jsonb_path_exists(jsonb_field, '$.**.id ? (@ == $id)', jsonb_build_object('id', :id))"但是,jsonb_path_exists()不能在列jsonb_field上使用索引
https://stackoverflow.com/questions/73111900
复制相似问题