scienta/doctrine-json-functions

Doctrine 的扩展集合,增加了对 JSON 查询函数的支持。

6.1.0 2024-04-10 07:24 UTC

README

Latest Stable Version Total Downloads License

DoctrineJsonFunctions

Doctrine 2+ 的扩展集合,增加了对 JSON 函数的支持。+MySQL、MariaDb 和 PostgreSQL 都支持这些函数。

目录

变更日志

每个 GitHub 版本的变更都会在变更日志中记录。您可以在以下位置找到概述:https://github.com/ScientaNL/DoctrineJsonFunctions/releases

安装

推荐通过 Composer 安装 DoctrineJsonFunctions。

运行以下命令安装软件包

composer require scienta/doctrine-json-functions

或者,您可以下载 源代码文件 并解压。

测试

此存储库使用 phpunit 进行测试。如果您只想运行测试,可以使用 docker composer 图像安装并运行 phpunit。有一个 docker-compose 文件具有正确的挂载,但如果您只想使用 docker,可以运行以下命令

php8

docker run -it -v ${PWD}:/app scienta/php-composer:php8 /bin/bash -c "composer install && ./vendor/bin/phpunit"

函数注册

Doctrine ORM

Doctrine 文档:“DQL 用户定义函数”

<?php

use Scienta\DoctrineJsonFunctions\Query\AST\Functions\Mysql as DqlFunctions;

$config = new \Doctrine\ORM\Configuration();
$config->addCustomStringFunction(DqlFunctions\JsonExtract::FUNCTION_NAME, DqlFunctions\JsonExtract::class);
$config->addCustomStringFunction(DqlFunctions\JsonSearch::FUNCTION_NAME, DqlFunctions\JsonSearch::class);

$em = EntityManager::create($dbParams, $config);
$queryBuilder = $em->createQueryBuilder();

Symfony 带有 Doctrine 扩展包

Symfony 文档:“DoctrineBundle 配置”

# config/packages/doctrine.yaml
doctrine:
    orm:
        dql:
            string_functions:
                JSON_EXTRACT: Scienta\DoctrineJsonFunctions\Query\AST\Functions\Mysql\JsonExtract
                JSON_SEARCH: Scienta\DoctrineJsonFunctions\Query\AST\Functions\Mysql\JsonSearch

请注意,doctrine 缺少 boolean_functions 条目。您可以将布尔函数注册为 string_functions 并使用 = true 进行比较以避免 DQL 解析器错误。例如,要检查 JSONB 数组中是否存在元素,请使用 andWhere('JSONB_EXISTS(u.roles, :role) = true)

用法

请注意在创建表达式时的比较,并转义参数以使其成为有效的 JSON。

使用 Mysql 5.7+ JSON 操作符

$q = $queryBuilder
  ->select('c')
  ->from('Customer', 'c')
  ->where("JSON_CONTAINS(c.attributes, :certificates, '$.certificates') = 1");

$result = $q->execute(array(
  'certificates' => '"BIO"',
));

使用 PostgreSQL 9.3+ JSON 操作符

请注意需要使用函数名。此库不支持自定义操作符,如 @>

$q = $queryBuilder
  ->select('c')
  ->from('Customer', 'c')
  ->where("JSON_GET_TEXT(c.attributes, 'gender') = :gender");

 $result = $q->execute(array(
    'gender' => 'male',
 ));

布尔函数需要作为字符串函数注册并使用 true 进行比较,因为 Doctrine DQL 不了解布尔函数

$q = $queryBuilder
  ->select('c')
  ->from('Customer', 'c')
  ->where('JSONB_CONTAINS(c.roles, :role) = true');

 $result = $q->execute(array(
    'role' => 'ROLE_ADMIN',
 ));

使用 SQLite JSON 操作符

$q = $queryBuilder
  ->select('c')
  ->from('Customer', 'c')
  ->where("JSON_EXTRACT(c.attributes, '$.gender') = :gender");

 $result = $q->execute();

DQL 函数

此库提供以下 DQL 函数集。

Mysql 5.7+ JSON 操作符

注意,如果兼容,您可以使用MySQL运算符与MariaDb数据库一起使用。

MariaDb 10.2.3 JSON运算符

  • JSON_VALUE(json_doc, path)
    • 返回由路径指定的标量。如果没有匹配项,则返回NULL。
  • JSON_EXISTS(json_doc, path)
    • 确定指定的JSON值是否存在于给定的数据中。如果找到,则返回1,如果没有找到,则返回0,或者如果任何输入为NULL,则返回NULL。
  • JSON_QUERY(json_doc, path)
    • 给定一个JSON文档,返回由路径指定的对象或数组。如果没有提供有效的JSON文档,或者没有匹配项,则返回NULL。

MariaDb 10.2.4 JSON运算符

MariaDb 10.7.0 JSON运算符

  • JSON_EQUALS(json_doc, json_doc)
    • 检查两个JSON对象之间是否存在相等性。如果存在,返回1;如果不存在,返回0;如果任何参数为null,返回NULL。
  • JSON_NORMALIZE(json_doc)
    • 递归排序键并删除空格,允许比较JSON文档的相等性。

PostgreSQL 9.3+ JSON 操作符

实现了对JSON运算符的基本支持。即使在Doctrine\DBAL v2.5中也可以使用。有关JSON运算符的官方文档,请参阅此处

  • JSONB_CONTAINS(jsonb, jsonb)
    • 扩展为jsonb @> jsonb
  • JSONB_EXISTS(jsonb, text)
    • 作为JSONB_EXISTS(jsonb, text)执行,等同于jsonb ? text
  • JSONB_EXISTS_ALL(jsonb, array)
    • 作为JSONB_EXISTS_ALL(jsonb, array)执行,等同于jsonb ?& array
  • JSONB_EXISTS_ANY(jsonb, array)
    • 作为JSONB_EXISTS_ANY(jsonb, array)执行,等同于jsonb ?| array
  • JSONB_IS_CONTAINED(jsonb, jsonb)
    • 扩展为jsonb <@ jsonb
  • JSONB_INSERT
    • 按原样执行
  • JSON_EXTRACT_PATH
    • 按原样执行
  • JSON_GET(jsondoc, path)
    • 如果path为数字,则扩展为jsondoc->path(与JSON数组一起使用)
    • 如果path为非数字,则扩展为jsondoc->'path'(与JSON对象一起使用)
  • JSON_GET_TEXT(jsondoc, path)
    • 如果path为数字,则扩展为jsondoc->>path(与JSON数组一起使用)
    • 如果path为非数字,则扩展为jsondoc->>'path'(与JSON对象一起使用)
  • JSON_GET_PATH(jsondoc, path)
    • 扩展为jsondoc#>'path'
  • JSON_GET_PATH_TEXT(jsondoc, path)
    • 扩展为jsondoc#>>'path'

请注意,不支持JSON运算符的链式调用。

SQLite JSON1扩展运算符

支持所有在JSON1扩展文档中看到的标量函数和聚合函数。

标量函数

  • JSON(json)
    • 验证其参数是否为有效的JSON字符串,并返回该JSON字符串的压缩版本。
  • JSON_ARRAY([val[, val] ...])
    • 接受零个或多个参数,并返回由这些参数组成的良好格式化的JSON数组。
  • JSON_ARRAY_LENGTH(json[, path])
    • 返回JSON数组json中的元素数量,如果json是除数组之外的任何JSON值,则返回0。
  • JSON_EXTRACT(json, path[, path ], ...)
    • 从良好格式化的JSON中提取并返回一个或多个值。
  • JSON_INSERT(json[, path, value],...)
    • 给定零个或多个路径和值的组合,它将在json中插入(不覆盖)每个值到其对应的路径。
  • JSON_OBJECT(label, value[, label, value], ...)
    • 接受零个或多个参数对,并返回由这些参数组成的好格式化JSON对象。
  • JSON_PATCH(target, patch)
    • patch应用于target
  • JSON_QUOTE(value)
    • 将SQL value(数字或字符串)转换为相应的JSON表示。
  • JSON_REMOVE(json[, path], ...)
    • 删除每个给定路径上的值。
  • JSON_REPLACE(json[, path, value],...)
    • 给定零个或多个路径和值的组合,它将覆盖json中对应路径上的每个值。
  • JSON_SET(json[, path, value],...)
    • 给定零个或多个路径和值的组合,它将在json中插入或覆盖每个值到其对应的路径。
  • JSON_TYPE(json[, path])
    • 返回jsonpath处的值的类型。
  • JSON_VALID(json)
    • 如果参数json是良好格式化的JSON,则返回1;否则返回0。

聚合函数

  • JSON_GROUP_ARRAY(value)
    • 返回由聚合中的所有value组成的JSON数组。
  • JSON_GROUP_OBJECT(name, value)
    • 返回由聚合中的所有name/value对组成的JSON对象。

可扩展性和数据库支持

架构

平台函数类的命名规则是

Scienta\DoctrineJsonFunctions\Query\AST\Functions\$platformName\$functionName

添加新平台

要添加对新平台的支持,您只需创建新的文件夹 Scienta\DoctrineJsonFunctions\Query\AST\Functions\$platformName 并根据命名规则在该文件夹中实现所需的功能。

添加新功能

如果您想向这个库添加新功能,请随意将其分叉并创建带有您实现内容的拉取请求。请记住,更新文档以包含您的新功能。

另请参阅

dunglas/doctrine-json-odm:将普通的PHP对象序列化/反序列化为JSON列。