-
Notifications
You must be signed in to change notification settings - Fork 73
Document json(field,path) function
#539
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
20 commits
Select commit
Hold shift + click to select a range
e7d49c3
start on docs for json queries
br41nslug e9e3fee
add new env var
br41nslug 3fdd13c
updated docs
br41nslug c7465c6
Merge branch 'main' into json-query-docs
br41nslug f15505c
remove leading dots
br41nslug 54da3ce
Merge branch 'json-query-docs' of https://github.com/directus/docs in…
br41nslug c2c963f
removed error handling
br41nslug b77ca64
removed useless unsupported reasons
br41nslug 44594d4
cleanup database specific over-explaining
br41nslug 4c2d99e
keep function signature and add callout
br41nslug 99c858a
Update content/_partials/json-function.md
br41nslug 4f6e0dd
Update content/_partials/json-function.md
br41nslug 3f28193
close out the callout
br41nslug 5182fa8
Merge branch 'json-query-docs' of https://github.com/directus/docs in…
br41nslug 7d6a1f6
fix table
br41nslug 18043c0
Apply suggestion from @ComfortablyCoding
ComfortablyCoding 6774ed3
Apply suggestion from @ComfortablyCoding
ComfortablyCoding ea7a484
tweaks
ComfortablyCoding 974fd25
Update json-function.md
ComfortablyCoding d03e484
Merge branch 'main' into json-query-docs
ComfortablyCoding File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,215 @@ | ||
| ## The `json(field, path)` Function | ||
|
|
||
| The `json(field, path)` function extracts the value from the specified path in a JSON field and returns it as a separate field in the query response. It is used in the `fields` query parameter alongside regular field names and other field functions. | ||
|
|
||
|
|
||
| ::callout{icon="material-symbols:warning-rounded" color="warning"} | ||
|
|
||
| **Supported Paramaters** | ||
| the `json(field, path)` function is currently only supported for use in the `fields` query parameter. | ||
|
|
||
| :: | ||
|
|
||
| ### Syntax | ||
|
|
||
| ``` | ||
| json(field, path) | ||
| ``` | ||
|
|
||
| - **`field`** — the name of a JSON column in the collection (or a relational path to one, see [Relational Queries](#relational-queries)). | ||
br41nslug marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| - **`path`** — a dot-and-bracket notation path to the value you want to extract from within the JSON document. | ||
br41nslug marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| Both arguments are required and separated by a comma. | ||
|
|
||
| ### Path Notation | ||
|
|
||
| Paths use dot notation for object keys and bracket notation for array indices. | ||
|
|
||
| | Pattern | Example | Meaning | | ||
| |---|---|---| | ||
| | `key` | `color` | Top-level key | | ||
| | `a.b.c` | `settings.theme.color` | Nested keys | | ||
| | `[n]` | `tags[0]` | Array element at index `n` | | ||
| | `a[n].b` | `items[0].name` | Mixed object/array access | | ||
|
|
||
| **Examples:** | ||
|
|
||
| ``` | ||
| json(metadata, color) → top-level key | ||
| json(metadata, settings.theme) → nested object | ||
| json(data, items[0].name) → array element property | ||
| json(data, [0]) → first element of a top-level array | ||
| ``` | ||
|
|
||
| ### Response Format | ||
|
|
||
| Extracted values are returned as additional fields on each item using auto-generated aliases. The alias follows the pattern: | ||
|
|
||
| ``` | ||
| {field}_{path}_json | ||
| ``` | ||
|
|
||
| Special characters in the path (`[`, `]`, `.`) are replaced with underscores. For example: | ||
|
|
||
| | Request field | Response key | | ||
| |---|---| | ||
| | `json(metadata, color)` | `metadata_color_json` | | ||
| | `json(metadata, settings.priority)` | `metadata_settings_priority_json` | | ||
| | `json(data, items[0].name)` | `data_items_0_name_json` | | ||
|
|
||
| #### Example Request and Response | ||
|
|
||
| ```http | ||
| GET /items/articles?fields=id,title,json(metadata, color)&sort=title | ||
| ``` | ||
|
|
||
| ```json | ||
| { | ||
| "data": [ | ||
| { | ||
| "id": 1, | ||
| "title": "An Article", | ||
| "metadata_color_json": "blue" | ||
| } | ||
| ] | ||
| } | ||
| ``` | ||
|
|
||
| ### Relational Queries | ||
|
|
||
| `json(field, path)` can traverse relational fields to extract JSON values from related items. The relational path goes inside the first argument, before the JSON field name. | ||
|
|
||
| #### Many-to-One (M2O) | ||
|
|
||
| ``` | ||
| json(relation.json_field, path) | ||
| ``` | ||
|
|
||
| The extracted value is returned nested under the relational key in the response, alongside any other requested fields from that relation. | ||
|
|
||
| ```http | ||
| GET /items/articles?fields=id,title,category_id.name,json(category_id.metadata, color) | ||
| ``` | ||
|
|
||
| ```json | ||
| { | ||
| "data": [ | ||
| { | ||
| "id": 1, | ||
| "title": "An Article", | ||
| "category_id": { | ||
| "name": "Tech", | ||
| "metadata_color_json": "blue" | ||
| } | ||
| } | ||
| ] | ||
| } | ||
| ``` | ||
|
|
||
| Multiple `json(field, path)` extractions from the same relation are grouped under the same relational key: | ||
|
|
||
| ```http | ||
| GET /items/articles?fields=id,json(category_id.metadata, color),json(category_id.metadata, icon) | ||
| ``` | ||
|
|
||
| ```json | ||
| { | ||
| "data": [ | ||
| { | ||
| "category_id": { | ||
| "metadata_color_json": "blue", | ||
| "metadata_icon_json": "laptop" | ||
| } | ||
| } | ||
| ] | ||
| } | ||
| ``` | ||
|
|
||
| #### One-to-Many (O2M) | ||
|
|
||
| For O2M relations, each related item returns its own extracted value. The response is an array of objects, each containing the extracted key. | ||
|
|
||
| ```http | ||
| GET /items/articles/1?fields=id,json(comments.data, type) | ||
| ``` | ||
|
|
||
| ```json | ||
| { | ||
| "data": { | ||
| "id": 1, | ||
| "comments": [ | ||
| { "data_type_json": "review" }, | ||
| { "data_type_json": "feedback" }, | ||
| { "data_type_json": "question" } | ||
| ] | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| #### Many-to-Any (M2A) | ||
|
|
||
| For M2A relations, use the standard Directus collection scope syntax inside the first argument: | ||
|
|
||
| ``` | ||
| json(relation.item:collection_name.json_field, path) | ||
| ``` | ||
|
|
||
| ```http | ||
| GET /items/shapes/1?fields=id,json(children.item:circles.metadata, color) | ||
| ``` | ||
|
|
||
| ### Relational Depth Limit | ||
|
|
||
| `json(field, path)` will enforce a maximum relational depth (`MAX_RELATIONAL_DEPTH`, default `10`) limit for the `field` argument. This depth is calculated irrespective of the Path depth limit mentioned below | ||
|
|
||
| ``` | ||
| json(category_id.metadata, a.b.c.d.e) | ||
| ``` | ||
| This has a relational depth of **2** (`category_id` + `metadata`), regardless of how many segments are in the JSON path `a.b.c.d.e`. | ||
|
|
||
| Exceeding the relational depth will return an error. | ||
|
|
||
| ### JSON Path Depth Limit | ||
|
|
||
| In addition to a relation depth, `json(field, path)` will also enforce a path depth limit (`MAX_JSON_QUERY_DEPTH`, default `10`). This depth is calculated irrespective of the relational depth. | ||
|
|
||
| ``` | ||
| json(category_id.metadata, a[0].c.d.e.f.g.h.i.j) | ||
| ``` | ||
|
|
||
| The above example has a path depth of 10 and is allowed by default; adding one more segment exceeds the limit. | ||
|
|
||
| Exceeding the path depth limit returns an error. | ||
|
|
||
| ### Unsupported Path Expressions | ||
|
|
||
| The following path syntaxes are **not supported** and will return an error: | ||
|
|
||
| | Expression | Example | | ||
| |---|---| | ||
| | Empty brackets (wildcard) | `items[]` | | ||
| | `[*]` wildcard | `items[*].name` | | ||
| | `*` glob | `items.*` | | ||
| | JSONPath predicates | `items[?(@.price > 10)]` | | ||
| | `@` current node | `@.name` | | ||
| | `$` root | `$.name` | | ||
|
|
||
| ### Object Keys with Special Characters | ||
|
|
||
| The `json(field, path)` path syntax uses `.` as a separator between key segments. There is no escape mechanism for object keys that themselves contain dots, spaces, or other special characters. For example, if your JSON has a key `"first.name"`, there is no way to express that in the path — `json(data, first.name)` would be interpreted as nested access to key `first`, then key `name`. | ||
|
|
||
| Similarly, because MySQL and MariaDB path conversion uses dot-notation (`$.key.subkey`), keys containing characters that are special in that context (e.g., spaces) may not be reachable. PostgreSQL's parameterized `->?` approach is more permissive for unusual key names, but the input path format still does not provide an escaping mechanism. | ||
|
|
||
| ### Database-Specific Exceptions | ||
br41nslug marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| **SQLite** | ||
|
|
||
| - SQLite can return `0`/`1` isntead of `boolean` values. | ||
br41nslug marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| **MSSQL** | ||
|
|
||
| - Will always returns scalar values as **strings (`NVARCHAR`)**, even when the original JSON value is a number or boolean. For example, a JSON integer `42` will be returned as the string `"42"`. Your application should perform type coercion as needed. | ||
|
|
||
| **Oracle** | ||
|
|
||
| - Similar to MSSQL will also return scalar values as **strings**, regardless of the original JSON type (number, boolean, etc.). A JSON number `3.14` will be returned as `"3.14"`. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.