-
Notifications
You must be signed in to change notification settings - Fork 716
Operators for documents [Deprecated]
A new item type is introduced in MySQL that represents a JSON document, which will be validated during instantiation. With the new document type, we can now introduce new operators that are document specific because we can check that the operands are of document type.
To create a document item in SQL, you use the DOCUMENT()
built-in function, and pass a literal string that represents a JSON object. The result new item will be treated as a document item.
SELECT DOCUMENT ('{"k1":"v1","k2":true,"k3":3}');
-- JSON is validated
SELECT DOCUMENT('{"key"}');
ERROR HY000: Invalid JSON object: '{"key"}', pos 7, error 'Invalid JSON object'.
With the document item type, we introduced the following new operators:
-- TRUE
SELECT DOCUMENT('{"k1":"v1", "k2":"v2"}')
SIMILAR
DOCUMENT('{"k2":"v2", "k1":"v1"}');
-- TRUE
SELECT DOCUMENT('{"k1": [1, "bar", {"k11": "v11", "k12": "v12"}, [{"foo": "bar"}]], "k2": "v2"}')
SIMILAR
DOCUMENT('{"k2" : "v2", "k1": [1, "bar", {"k12": "v12", "k11": "v11"}, [{"foo": "bar"}]]}');
-- In where clause
SELECT id
FROM t1
WHERE doc.address NOT SIMILAR DOCUMENT('{"state":"NY", "zipcode":98767}');
Both operands must both be of the document type which can be a document column, document path, or a literal specified within the DOCUMENT()
function. It returns true if the left operand and the right operand contain the exact same key-value pairs, but order doesn't matter. For example, {"k1": "v1", "k2": "v2"}
and {"k2": "v2", "k1": "v1"}
are similar.
The order of elements in an array however do matter.
-- TRUE
SELECT DOCUMENT('{"k2":"v2"}')
SUBDOC
DOCUMENT('{"k1":"v1", "k2":"v2"}');
-- TRUE
SELECT DOCUMENT('{"k1":"v1", "k2":"v2"}')
CONTAINS
DOCUMENT('{"k2":"v2"}');
Both operands must both be of the document type which can be a document column, a document path, or a literal specified within the DOCUMENT()
function. It returns true if every key-value pair of the left operand is contained in the first level of the right operand. Again, order does not matter for key-value pairs but the level of nesting does matter.
-- TRUE
SELECT DOCUMENT('{"k1":"v1", "k2":"v2"}')
CONTAINS
DOCUMENT('{"k2":"v2"}');
This operator is the inverted version of SUBDOC, meaning that x SUBDOC y
is true if and only if y CONTAINS x
is true.
If you attempt to use CONTAINS
with any other type other than the document type, an error will be thrown.
-- TRUE (document type SIMILAR)
SELECT DOCUMENT('{"k1":"v1", "k2": "v2"}') LIKE DOCUMENT('{"k2": "v2", "k1": "v1"}');
-- TRUE (string matching)
SELECT DOCUMENT('{"k":"v"}') LIKE '{"k%';
-- FALSE (string matching)
SELECT DOCUMENT('{"k":"v"}') LIKE '{"k" :"v"}';
This is an existing SQL operator, but its behavior depends on the operand types.
- If both operands are documents (document column, document path, or literal using
DOCUMENT()
function), then the comparison is equivalent to that of SIMILAR. Every key-value pair must be matched, and the order of keys do not matter. - If only one operand is a document, the document operand is first casted to a string. After that, the normal LIKE logic will be evaluated. This allows one to compare a document with a string that has wildcards.
-- TRUE
SELECT DOCUMENT('{"key":[1,2,3]}') = DOCUMENT('{"key":[1,2,3]}');
This is an existing SQL operator, but its behavior depends on the operand types.
- If both operands are documents (document column, document path, or literal using
DOCUMENT()
function), the comparison is between the binary format of the two operands. It returns true if they contain exactly the same key-value pairs in the same order. - If only one operand is a document, it will first cast the document operand to a string, then proceed with the usual scalar equality comparison.
-- TRUE
SELECT DOCUMENT('{"key":[1,2,3]}') != DOCUMENT('{"key":[1,2]}');
SELECT DOCUMENT('{"key":[1,2,3]}') <> DOCUMENT('{"key":[1,2]}');
-- FALSE
SELECT DOCUMENT('{}') != '{}';
SELECT DOCUMENT('{}') <> '{}';
This is the negation of the =
operator.
We allow standard MySQL wildcards (%
, _
, etc) to be used in a JSON string value inside a DOCUMENT() function. Wildcards inside a key are not supported and treated as literal symbols.
-- TRUE
SELECT DOCUMENT('{"k":"v1"}') LIKE DOCUMENT('{"k":"v_"}');
-- TRUE
SELECT DOCUMENT('{"k":"v1", "k2":"v2"}') CONTAINS DOCUMENT('{"k":"%"}');
-- TRUE
SELECT DOCUMENT('["foo", 123, true]') SIMILAR DOCUMENT('["f_o", 123, true]');
-- TRUE
SELECT DOCUMENT('{"k":"%"}') SUBDOC DOCUMENT('{"k":"v1", "k2":"v2"}') ;
Documentation license here.
Installation
MyRocks
- Overview
- Transaction
- Backup
- Performance Tuning
- Monitoring
- Migration
- Internals
- Vector Database
DocStore
- Document column type
- Document Path: a new way to query JSON data
- Built-in Functions for JSON documents
MySQL/InnoDB Enhancements