Skip to content

Json Methods

Glynn Quelch edited this page Feb 9, 2022 · 5 revisions

JSON FUNCTIONALITY IS SET TO BE REFACTORED AND THIS API WILL CHANGE

Along side the ability to traverse and work with JSON documents using the Laravel style arrow selectors. We also have a collection of JSON helper methods, these allow for more complex functionality, while increasing readability.

if you wish to access these methods, please call jsonBuilder() before defining your query.

selectJson()

It is possible to select single values (either inner object/array or just values) from within JSON documents.

/**
 * @param string|Raw           $column   The Database column holding JSON document  
 * @param string|string[]|Raw  $nodes       Either single node, array of nodes or raw expression  
 * @param string               $alias       Sets the 'AS Alias'   
 * @return QueryBuildHandler
 */
public function selectJson($column, $nodes, $alias): QueryBuilderHandler

DB Table

id title authorData
1 5 Easy Rules Of Tree {"data":{"author_id":12, "author_name":"Sam"}}
2 The Death Of Lard {"data":{"author_id":42, "author_name":"James"}}
3 Is Bacon Still Relevant? {"data":{"author_id":12, "author_name":"Sam"}}
4 The Miracle Of Sponge {"data":{"author_id":24, "author_name":"Jane"}}

Usage

$builder->jsonBuilder()
    ->table('foo')
    ->select('id', 'title')
    ->selectJson('authorData',['data','author_name'], 'author')
    ->get()
  0 => {id: 1, title: "5 Easy Rules Of Tree", author: "Sam"},
  1 => {id: 2, title: "The Death Of Lard", author: "James"},
  2 => {id: 3, title: "Is Bacon Still Relevant?", author: "Sam"},
  3 => {id: 4, title: "The Miracle Of Sponge", author: "Jane"}

whereJson()

Also includes orWhereJson()

It is possible to select single values (either inner object/array or just values) from within JSON documents.

  • whereJson() - joins multiple Where Statements with 'AND'
  • orWhereJson() - joins multiple Where Statements with 'OR'
/**
 * @param string|Raw          $column   The database column which holds the JSON value
 * @param string|string[]|Raw $nodes    Either single node, array of nodes or raw expression
 * @param string|mixed|null   $operator Can be used as value, if 3rd arg not passed
 * @param mixed|null          $value    The value to match to the JSON value
 * @return QueryBuilderHandler
 */
public function whereJson($column, $nodes, $operator, $value ): QueryBuilderHandler

It is possible to omit the $operator value and it assumed as =

DB Table

id title authorData
1 5 Easy Rules Of Tree {"data":{"id":12, "name":"Sam"}}
2 The Death Of Lard {"data":{"id":42, "name":"James"}}
3 Is Bacon Still Relevant? {"data":{"id":12, "name":"Sam"}}
4 The Miracle Of Sponge {"data":{"id":24, "name":"Jane"}}

Usage

$builder->jsonBuilder()
    ->table('foo')
    ->whereJson('authorData',['data','id'], 12)
    ->orWhereJson('authorData',['data','id'], 24)
    ->get()

Results

  0 => {id: 1, title: "5 Easy Rules Of Tree", authorData: {"data":{"id":12, "name":"Sam"}}},
  1 => {id: 3, title: "Is Bacon Still Relevant?", authorData: {"data":{"id":12, "name":"Sam"}}}
  2 => {id: 4, title: "The Miracle Of Sponge", authorData: {"data":{"id":24, "name":"Jane"}}}

whereNotJson()

Also includes orWhereNotJson()

It is possible to create a `Where value inside JSON document doesn't match the operator and value defined.

  • whereNotJson() - joins multiple Where Statements with 'AND'
  • orWhereNotJson() - joins multiple Where Statements with 'OR'
/**
 * @param string|Raw          $column   The database column which holds the JSON value
 * @param string|string[]|Raw $nodes    Either single node, array of nodes or raw expression
 * @param string|mixed|null   $operator Can be used as value, if 3rd arg not passed
 * @param mixed|null          $value    The value to match to the JSON value
 * @return QueryBuilderHandler
 */
public function whereNotJson($column, $nodes, $operator, $value ): QueryBuilderHandler

It is possible to omit the $operator value and it assumed as =

DB Table

id title authorData
1 5 Easy Rules Of Tree {"data":{"id":12, "name":"Sam"}}
2 The Death Of Lard {"data":{"id":42, "name":"James"}}
3 Is Bacon Still Relevant? {"data":{"id":12, "name":"Sam"}}
4 The Miracle Of Sponge {"data":{"id":24, "name":"Jane"}}

Usage

$builder->jsonBuilder()
    ->table('foo')
    ->whereNotJson('authorData',['data','id'], 24)
    ->orWhereNotJson('authorData',['data','id'], 42)
    ->get()

Results

  0 => {id: 1, title: "5 Easy Rules Of Tree", authorData: {"data":{"id":12, "name":"Sam"}}},
  1 => {id: 3, title: "Is Bacon Still Relevant?", authorData: {"data":{"id":12, "name":"Sam"}}}

whereInJson()

Also includes orWhereInJson()

It is possible to create a `Where value inside JSON document doesn't match the operator and value defined.

  • whereInJson() - joins multiple WhereInJson Statements with 'AND'
  • orWhereInJson() - joins multiple WhereInJson Statements with 'OR'
/**
 * @param string|Raw          $column    The database column which holds the JSON value
 * @param string|string[]|Raw $nodes     Either single node, array of nodes or raw expression
 * @param mixed[]             $values    Array of values to look for a match in
 * @return QueryBuilderHandler
 */
public function whereInJson($column, $nodes, $values ): QueryBuilderHandler

DB Table

id name choices
1 Glynn {"data":{"colour":"red", "flavour":"apple"}}
2 Oliver {"data":{"colour":"red", "flavour":"berry"}}
3 Dexter {"data":{"colour":"green", "flavour":"cream"}}
4 Mary {"data":{"colour":"blue", "flavour":"bacon"}}

Usage

$builder->jsonBuilder()
    ->table('foo')
    ->whereInJson('choices',['data','colour'], ['green', 'yellow'])
    ->orWhereInJson('choices',['data','flavour'], ['bacon', 'cheese', 'pear'])
    ->get()

Results

  0 => {id: 3, name: "Dexter", choices: {"data":{"colour":"green", "flavour":"cream"}}},
  1 => {id: 4, name: "Mary", choices: {"data":{"colour":"blue", "flavour":"bacon"}}}

❗ Don't forget you can use bindings to help avoid XSS injection

->whereJson('column', ['json','object'], [Bindings::asString($variable1), Bindings::asString($variable2)]);

whereNotInJson()

Also includes orWhereNotInJson()

It is possible to create a `Where value inside JSON document doesn't match the operator and value defined.

  • whereNotInJson() - joins multiple WhereNotInJson Statements with 'AND'
  • orWhereNotInJson() - joins multiple WhereNotInJson Statements with 'OR'
/**
 * @param string|Raw          $column    The database column which holds the JSON value
 * @param string|string[]|Raw $nodes     Either single node, array of nodes or raw expression
 * @param mixed[]             $values    Array of values to look for a match NOT in
 * @return QueryBuilderHandler
 */
public function whereNotInJson($column, $nodes, $values ): QueryBuilderHandler

DB Table

id name choices
1 Glynn {"data":{"colour":"red", "flavour":"apple"}}
2 Oliver {"data":{"colour":"red", "flavour":"berry"}}
3 Dexter {"data":{"colour":"green", "flavour":"cream"}}
4 Mary {"data":{"colour":"blue", "flavour":"bacon"}}

Usage

$builder->jsonBuilder()
    ->table('foo')
    ->whereNotInJson('choices',['data','colour'], ['green', 'yellow'])
    ->orWhereNotInJson('choices',['data','flavour'], ['bacon', 'cheese', 'pear'])
    ->get()

Results

  0 => {id: 1, name: "Glynn", choices: {"colour":"red", "flavour":"apple"}}},
  1 => {id: 2, name: "Oliver", choices: {"data":{"colour":"red", "flavour":"berry"}}}

whereBetweenJson()

Also includes orWhereBetweenJson()

It is possible to create a `Where value inside JSON document doesn't match the operator and value defined.

  • whereBetweenJson() - joins multiple whereBetweenJson Statements with 'AND'
  • orWhereBetweenJson() - joins multiple whereBetweenJson Statements with 'OR'
/**
 * @param string|Raw          $column    The database column which holds the JSON value
 * @param string|string[]|Raw $nodes     Either single node, array of nodes or raw expression
 * @param int|float|Raw       $valueFrom The min value
 * @param int|float|Raw       $valueTo   The max value
 * @return QueryBuilderHandler
 */
public function whereBetweenJson($column, $nodes, $valueFrom, $valueTo ): QueryBuilderHandler

DB Table

id name results
1 Glynn {"data":{"step1":2, "step2":8}}
2 Oliver {"data":{"step1":4, "step2":3}}
3 Dexter {"data":{"step1":3, "step2":2}}
4 Mary {"data":{"step1":9, "step2":7}}

Usage

$builder->jsonBuilder()
    ->table('foo')
    ->whereBetweenJson('choices',['data','step1'], 7, 9)
    ->orWhereBetweenJson('choices',['data','step2'], 7, 9)
    ->get()

Results

  0 => {id: 1, name: "Glynn", results: {"data":{"step1":2, "step2":8}}},
  1 => {id: 4, name: "Mary", results:  {"data":{"step1":9, "step2":7}}}

orderByJson()

It is possible to order a query by a single or multiple values. The basic arrow selectors will not do any casting of the data value and treat as a basic string value. This can be controlled using the following flags.

/**
 * @param string|Raw           $column   The Database column holding JSON document  
 * @param string|string[]|Raw  $nodes       Either single node, array of nodes or raw expression  
 * @param string               $direction   Direction 'ASC' or 'DESC'.   
 * @return QueryBuildHandler
 */
public function orderByJson($column, $nodes, $direction='ASC'): QueryBuilderHandler

DB Table

id title metaData
1 Some Tile {"stats":{"likes":450, "dislikes":5}}
2 Foo Bar {"stats":{"likes":45, "dislikes":500}}
3 Words {"stats":{"likes":85463, "dislikes":785}}
4 Examples {"stats":{"likes":45, "dislikes":14}}
Usage
$builder->jsonBuilder()
    ->table('foo')
    ->orderByJson('metaData',['stats','likes'], 'DESC')
    ->orderByJson('metaData',['stats','dislikes'], 'ASC')
    ->get()

Results

  0 => {id: 3, string: "Words", metaData:{stats:{likes:85463, dislikes:785}}},
  1 => {id: 1, string: "Some Tile", metaData: {stats:{likes:450,dislikes:5}}},
  2 => {id: 4, string: "Examples", metaData: {stats:{likes:45,dislikes:14}}}},
  3 => {id: 2, string: "Foo Bar",  metaData: {stats:{likes:45,dislikes:500}}}
Clone this wiki locally