关于 postgres json 函数与 sqlite3 json 函数语法的问题,其中 jsonpath 是关注的

问题描述 投票:0回答:0

我正在做一个项目,我有一个 java 服务与存储 json 对象的数据库对话。 json 对象称为

scanResultCollection
。它有一个名为
organization
的顶级属性。当以独立模式(即 - 在我的工作站上)运行时,我已经设置了它使用 sqlite 的地方。部署后它会自动切换到 postgres。

这里是相关的一段代码:

        EntityManager entityManager = ctx.attribute(App.RESULT_TABLE_ENTITY_MANAGER);
        var criteriaBuilder = entityManager.getCriteriaBuilder();
        CriteriaQuery<Result> criteriaQuery = criteriaBuilder.createQuery(Result.class);
        Root<Result> root = criteriaQuery.from(Result.class);

        var organizationPath = JPathHelpers.getJsonPathFor(
                List.of(ScanResultCollection.ORGANIZATION_KEY)
        );
        LOG.info("organizationPath is: {}", organizationPath);
        var predicate = criteriaBuilder.equal(
                criteriaBuilder.function(
                        "jsonb_extract_path_text",
                        //"json_extract", // @TODO this should be a config value as it's db specific
                        String.class,
                        // TODO see note in Result entity for why we're not using the generated metamodel for now
                        // TODO when looking into the ScanResultCollection json object
                        root.get(SCAN_RESULT_COLLECTION_ATTRIBUTE),
                        //criteriaBuilder.literal(organizationPath)
                        criteriaBuilder.literal("organization")
                ),
                org
        );

        criteriaQuery.select(root).where(predicate);
        var query = entityManager.createQuery(criteriaQuery);
        List<Result> results = query.getResultList();

基本上发生的事情是调用者为

organization
提供了一个值,我们正在努力查询数据库以查找具有与调用者提供的值匹配的
scanResultCollection
值的所有
organization
对象。

对于 sqlite,函数

json_extract
正在被使用,并且
organizationPath
的值解析为
$.organization
。所有这些都很完美。

对于 postgres,我们需要将函数名称更改为

jsonb_extract_path_text
- 没问题,因为显然 postgres 是与 sqlite 不同的数据库系统。让我难过一整天的是
"$.organizationPath"
不起作用并且总是返回零结果。为了让 postgres 执行与 sqlite 相同的工作,有必要提供字符串
"organization"
而不是 jsonpath 形式
"$.organization"
.

docs 声明参数是 JSONPath 类型,最终我发现对于 Postgres

JSONPath
的含义与它在我所知道的几乎任何其他用例中的含义不同 - 特别是在
$
的含义方面.

这是我的问题

  • 为什么
    "$.organization"
    在 sqlite 和 postgres 上下文中都不起作用?看起来在 Postgres 中(实际上在 OracleSqlServer 中)
    $
    “表示正在查询的 JSON 值的变量(上下文项)”。 “上下文项”不是“当前项”吗?在这种情况下,它类似于根 JSON 元素?
  • 有没有办法让我使用 hibernate(或其他一些 java 库)来同质化 JSONPath 语法,以便它可以跨多个 SQL 数据库系统工作?鉴于我在文档中看到的内容,我的预感是相同的语法适用于 Postgres、Oracle 和 SqlServer,但不适用于 Sqlite。对于这个用例来说,这没什么大不了的,因为我可以轻松添加另一个配置值,该值可以在上下文适当的 JSONPath 语法中交换,但如果有办法做到这一点,我想知道如何做以供将来参考。

归根结底,令我感到奇怪的是,主要的 SQL 数据库供应商会以一种与世界其他地方使用它的方式不兼容的方式实现像 JSONPath 这样常见的事实上标准化的东西——这告诉我我可能遗漏了一些东西,如果是的话我很好奇那东西可能是什么......

提前!

java postgresql sqlite jsonpath
© www.soinside.com 2019 - 2024. All rights reserved.