java - 使用条件 API 搜索 jsonb 字段
问题描述
我有一个实体,其中有一个 jsonb 类型的内容字段。复杂的 json 存储在该字段中。我需要在此字段上进行选择。我使用标准 API。这样的查询有效:
public Predicate getPredicate(){
Expression<String> function = builder.function("jsonb_extract_path_text",
String.class,
root.<String>get("content"),
builder.literal("unit"),
builder.literal("id")
);
return builder.like(
function,
"%" + value + "%"
);
}
JSON 看起来像这样:
{
"unit":{
"id":"58bd51815744bf06e001b57b",
"name":"my name",
"another":{
"anotherId":"45545454"
}
}
}
问题是 JSON 的搜索条件可能完全不同。也许有一个搜索:unit.id = 58bd51815744bf06e001b57b。可能是这样的:unit.another.anotherId = 45545454。甚至可能是这样:unit.id = 58bd51815744bf06e001b57b和unit.name = "my name"。
我想我可以像这样解决我的问题:
Expression<String> function = builder.function("jsonb_extract_path_text",
String.class,
root.<String>get("content"),
builder.literal("$.unit.id")
);
但由于某种原因,这不起作用。任何想法如何解决这一问题?
解决方案
我找到了解决方案:所以我使用 Spring 数据进行搜索
EntityAbstract one = entityRepository.findOne(((Specification<EntityAbstract>)
(root, query, builder) -> {
Expression<?>[] expressions = {root.<String>get("content"), builder.literal("unit"), builder.literal("id")};
return toPredicate(root, query, builder, projectionName, expressions);
}
)).orElseThrow(() -> new ResourceNotFoundException("Entity not found"));
这就是使用 Criteria Builder 的方法的样子
public Predicate toPredicate(Root<EntityAbstract> root, CriteriaQuery<?> query, CriteriaBuilder builder, String value, Expression<?>[] args) {
Expression<String> function = builder.function("jsonb_extract_path_text",
String.class, args
);
return builder.like(
function,
"%" + value + "%"
);
}
也就是说,我需要形成一个所需长度的数组(表达式),这并不难
推荐阅读
- c# - 如何将此 VB.Net 翻译成 C#?
- c# - 是否使用增量运算符作为打破 C# 中嵌套循环的正确方法?
- macos - 如何在 macOS Big Sur 中将闪存驱动器格式化为 FAT32?
- google-cloud-platform - 使用 GCP 令牌、terraform 和 vault 创建项目时出现权限错误
- c - 子进程在 c 中未正确终止
- amazon-web-services - 如何在不是“@app.lambda_function()”的测试中调用 AWS Chalice 函数
- rust - 过早地超出范围
- java - Clickhouse 异常:超出内存限制(总计):28.13 GiB(尝试分配 4543835 字节的块)
- javascript - javascript groupby键并在表格中打印
- sql - 创建表时出现错误 ORA-01727: SQLOracle 数据库中的数值精度说明符超出范围(1 到 38)