Doctrine DQL 函数用于 SQL JSON 数据类型
A set of extensions to Doctrine ORM that add support for JSON functions in DQL (Doctrine Query Language). Supports MySQL, MariaDB, PostgreSQL, SQLite, and SQL Server.
Doctrine ORM does not natively support database-specific JSON functions in DQL. This library bridges that gap by registering custom DQL function nodes for each supported platform. Each function validates at SQL generation time that the correct database platform is in use, so you get an early error if a function is used against the wrong database.
| Database | Functions |
|---|---|
| MySQL 5.7+ / MariaDB | JSON_ARRAY, JSON_ARRAY_APPEND, JSON_ARRAY_INSERT, JSON_ARRAYAGG, JSON_CONTAINS, JSON_CONTAINS_PATH, JSON_DEPTH, JSON_EXTRACT, JSON_INSERT, JSON_KEYS, JSON_LENGTH, JSON_MERGE, JSON_MERGE_PATCH, JSON_MERGE_PRESERVE, JSON_OBJECT, JSON_OBJECTAGG, JSON_OVERLAPS, JSON_PRETTY, JSON_QUOTE, JSON_REMOVE, JSON_REPLACE, JSON_SEARCH, JSON_SET, JSON_TYPE, JSON_UNQUOTE, JSON_VALID |
| MySQL 8.0.21+ only | JSON_VALUE |
| MariaDB only | JSON_COMPACT, JSON_DETAILED, JSON_EQUALS, JSON_EXISTS, JSON_LOOSE, JSON_NORMALIZE, JSON_QUERY, JSON_VALUE |
| PostgreSQL 9.3+ | JSONB_CONTAINS, JSONB_EXISTS, JSONB_EXISTS_ALL, JSONB_EXISTS_ANY, JSONB_INSERT, JSONB_IS_CONTAINED, JSON_EXTRACT_PATH, JSON_GET, JSON_GET_PATH, JSON_GET_PATH_TEXT, JSON_GET_TEXT |
| SQLite (json1 ext.) | JSON, JSON_ARRAY, JSON_ARRAY_LENGTH, JSON_EXTRACT, JSON_GROUP_ARRAY, JSON_GROUP_OBJECT, JSON_INSERT, JSON_OBJECT, JSON_PATCH, JSON_QUOTE, JSON_REMOVE, JSON_REPLACE, JSON_SET, JSON_TYPE, JSON_VALID |
| SQL Server 2016+ | JSON_VALUE |
doctrine/orm: ^2.19 or ^3doctrine/dbal: ^3.2 or ^4doctrine/lexer: ^2.0 or ^3.0Install via Composer:
composer require scienta/doctrine-json-functionsAll functions must be registered as custom string functions in the Doctrine configuration before they can be used in DQL. Each function class exposes a FUNCTION_NAME constant that matches the DQL keyword you use in queries.
Note on boolean functions: Doctrine DQL does not have a native boolean function type (upstream issue). Register boolean-returning functions (e.g.,
JSONB_CONTAINS,JSON_CONTAINS) asstring_functionsand compare them explicitly with= trueor= 1in your DQL to avoid parser errors.
addCustomStringFunction(MysqlFunctions\JsonExtract::FUNCTION_NAME, MysqlFunctions\JsonExtract::class);
$config->addCustomStringFunction(MysqlFunctions\JsonContains::FUNCTION_NAME, MysqlFunctions\JsonContains::class);
$config->addCustomStringFunction(MysqlFunctions\JsonUnquote::FUNCTION_NAME, MysqlFunctions\JsonUnquote::class);
$em = EntityManager::create($dbParams, $config);…Use the registered DQL function names directly in your DQL queries or query builders. JSON path expressions must use single-quoted strings in DQL (not double-quoted).
…PostgreSQL operators (->, ->>, @>, ?, etc.) are exposed as named DQL functions because Doctrine DQL does not support custom operators.
…PostgreSQL operator chaining (e.g.,
col->'a'->'b') is not supported. UseJSON_GET_PATH(works on bothjsonandjsonb) orJSON_EXTRACT_PATH(jsoncolumns only) instead.
// Extract a field from a JSON column
$results = $queryBuilder
->select('c')
->from('App\Entity\Customer', 'c')
->where("JSON_EXTRACT(c.attributes, '$.country') = :country")
->setParameter('country', 'NL')
->getQuery()->getResult();// Extract a scalar value from a JSON column
$results = $queryBuilder
->select('c')
->from('App\Entity\Customer', 'c')
->where("JSON_VALUE(c.attributes, '$.country') = :country")
->setParameter('country', 'NL')
->getQuery()->getResult();To apply type conversion, use
CASToutside the function:CAST(JSON_VALUE(c.attributes, '$.score') AS DECIMAL(4,2))
All functions in the Scienta\DoctrineJsonFunctions\Query\AST\Functions\Mysql namespace unless noted. Functions marked as shared also work on MariaDB (they are registered under the MySQL namespace but validate against AbstractMySQLPlatform / MariaDBPlatform).
| DQL Function | Class | Signature | Description |
|---|---|---|---|
JSON_ARRAY |
JsonArray |
JSON_ARRAY([val, ...]) |
Creates a JSON array from arguments |
JSON_ARRAY_APPEND |
JsonArrayAppend |
JSON_ARRAY_APPEND(doc, path, val[, ...]) |
Appends values to JSON arrays |
JSON_ARRAY_INSERT |
JsonArrayInsert |
JSON_ARRAY_INSERT(doc, path, val[, ...]) |
Inserts into a JSON array |
JSON_ARRAYAGG |
JsonArrayAgg |
JSON_ARRAYAGG(value) |
Aggregate: builds a JSON array from rows |
JSON_CONTAINS |
JsonContains |
JSON_CONTAINS(doc, val[, path]) |
Returns 1 if doc contains val |
JSON_CONTAINS_PATH |
JsonContainsPath |
JSON_CONTAINS_PATH(doc, one_or_all, path[, ...]) |
Returns 1 if path(s) exist |
JSON_DEPTH |
JsonDepth |
JSON_DEPTH(doc) |
Returns maximum depth of document |
JSON_EXTRACT |
JsonExtract |
JSON_EXTRACT(doc, path[, ...]) |
Extracts data from a JSON document |
JSON_INSERT |
JsonInsert |
JSON_INSERT(doc, path, val[, ...]) |
Inserts data into a JSON document |
JSON_KEYS |
JsonKeys |
JSON_KEYS(doc[, path]) |
Returns top-level keys as a JSON array |
JSON_LENGTH |
JsonLength |
JSON_LENGTH(doc[, path]) |
Returns the length of a JSON document or value |
JSON_MERGE |
JsonMerge |
JSON_MERGE(doc, doc[, ...]) |
Merges JSON documents (deprecated alias) |
JSON_MERGE_PATCH |
JsonMergePatch |
JSON_MERGE_PATCH(doc, doc[, ...]) |
RFC 7396 merge patch |
JSON_MERGE_PRESERVE |
JsonMergePreserve |
JSON_MERGE_PRESERVE(doc, doc[, ...]) |
Merges preserving duplicate keys |
JSON_OBJECT |
JsonObject |
JSON_OBJECT([key, val, ...]) |
Creates a JSON object |
JSON_OBJECTAGG |
JsonObjectAgg |
JSON_OBJECTAGG(key, val) |
Aggregate: builds a JSON object from rows |
JSON_OVERLAPS |
JsonOverlaps |
JSON_OVERLAPS(doc1, doc2) |
Returns 1 if documents share key-value pairs or array elements |
JSON_PRETTY |
JsonPretty |
JSON_PRETTY(val) |
Returns pretty-printed JSON |
JSON_QUOTE |
JsonQuote |
JSON_QUOTE(val) |
Quotes a string as a JSON value |
JSON_REMOVE |
JsonRemove |
JSON_REMOVE(doc, path[, ...]) |
Removes data from a JSON document |
JSON_REPLACE |
JsonReplace |
JSON_REPLACE(doc, path, val[, ...]) |
Replaces existing values |
JSON_SEARCH |
JsonSearch |
JSON_SEARCH(doc, one|all, str[, escape[, path...]]) |
Returns path to a string in a document |
JSON_SET |
JsonSet |
JSON_SET(doc, path, val[, ...]) |
Inserts or updates values |
JSON_TYPE |
JsonType |
JSON_TYPE(val) |
Returns the JSON type string |
JSON_UNQUOTE |
JsonUnquote |
JSON_UNQUOTE(val) |
Unquotes a JSON value |
JSON_VALID |
JsonValid |
JSON_VALID(val) |
Returns 1 if value is valid JSON |
MySQL functions that also apply to MariaDB use
MysqlAndMariadbJsonFunctionNodeas their base, which validates againstAbstractMySQLPlatform(DBAL 3.3+) orMySQLPlatform(older DBAL).
| DQL Function | Class | Signature | Description |
|---|---|---|---|
JSON_VALUE |
JsonValue |
JSON_VALUE(doc, path[, RETURNING type]) |
Extracts a scalar value; supports RETURNING DECIMAL(n,m), RETURNING CHAR, etc. |
This function uses MysqlJsonFunctionNode and only works on MySQL (not MariaDB).
Namespace: Scienta\DoctrineJsonFunctions\Query\AST\Functions\Mariadb
| DQL Function | Class | Available Since | Description |
|---|---|---|---|
JSON_VALUE |
JsonValue |
MariaDB 10.2.3 | Extracts a scalar value at a path |
JSON_EXISTS |
JsonExists |
MariaDB 10.2.3 | Returns 1 if path exists in document |
JSON_QUERY |
JsonQuery |
MariaDB 10.2.3 | Returns an object or array at a path |
JSON_COMPACT |
JsonCompact |
MariaDB 10.2.4 | Removes unnecessary whitespace from JSON |
JSON_DETAILED |
JsonDetailed |
MariaDB 10.2.4 | Returns human-readable formatted JSON |
JSON_LOOSE |
JsonLoose |
MariaDB 10.2.4 | Adds spaces for readability |
JSON_EQUALS |
JsonEquals |
MariaDB 10.7.0 | Returns 1 if two JSON documents are equal |
JSON_NORMALIZE |
JsonNormalize |
MariaDB 10.7.0 | Sorts keys and removes spaces for comparison |
MySQL operators like
JSON_EXTRACTare also available on MariaDB — register them from theMysqlnamespace.
Namespace: Scienta\DoctrineJsonFunctions\Query\AST\Functions\Postgresql
PostgreSQL JSON operators are wrapped as named functions. SQL output uses the native operators.
| DQL Function | Class | SQL Equivalent | Description |
|---|---|---|---|
JSONB_CONTAINS |
JsonbContains |
jsonb @> jsonb |
Returns true if left contains right |
JSONB_EXISTS |
JsonbExists |
native jsonb_exists(jsonb, text) |
Returns true if key exists in JSONB |
JSONB_EXISTS_ALL |
JsonbExistsAll |
native jsonb_exists_all(jsonb, text[]) |
Returns true if all keys exist |
JSONB_EXISTS_ANY |
JsonbExistsAny |
native jsonb_exists_any(jsonb, text[]) |
Returns true if any key exists |
JSONB_INSERT |
JsonbInsert |
native jsonb_insert(...) |
Inserts a value into a JSONB document |
JSONB_IS_CONTAINED |
JsonbIsContained |
jsonb key (numeric: -> int, text: -> 'key') |
Returns a JSON field/element |
JSON_GET_TEXT |
JsonGetText |
json ->> key |
Returns a JSON field/element as text |
JSON_GET_PATH |
JsonGetPath |
json #> '{path}' |
Extracts a sub-object at path array |
JSON_GET_PATH_TEXT |
JsonGetPathText |
json #>> '{path}' |
Extracts a sub-object at path array as text |
Boolean functions (JSONB_CONTAINS, JSONB_EXISTS, JSONB_EXISTS_ALL, JSONB_EXISTS_ANY, JSONB_IS_CONTAINED) must be compared with = true due to the Doctrine DQL boolean function limitation:
->andWhere('JSONB_CONTAINS(e.data, :val) = true')Namespace: Scienta\DoctrineJsonFunctions\Query\AST\Functions\Sqlite
SQLite must have the json1 extension enabled (it is compiled in by default since SQLite 3.38.0).
| DQL Function | Class | Signature | Description |
|---|---|---|---|
JSON |
Json |
JSON(json) |
Validates and minifies a JSON string |
JSON_ARRAY |
JsonArray |
JSON_ARRAY([val, ...]) |
Creates a JSON array |
JSON_ARRAY_LENGTH |
JsonArrayLength |
JSON_ARRAY_LENGTH(json[, path]) |
Returns the number of elements in an array |
JSON_EXTRACT |
JsonExtract |
JSON_EXTRACT(json, path[, ...]) |
Extracts one or more values |
JSON_INSERT |
JsonInsert |
JSON_INSERT(json[, path, value, ...]) |
暂无开放 Issues,或尚未同步最近议题。