这里还有一些解释:
The way JSONiq updates work is identical to the way XQuery updates work. JSONiq updates are declarative: a JSONiq update program returns, in addition to an empty sequence in the data model, what is called a pending update list (PUL), which is a list of updates (deletions, replacements, renamings, insertions, etc) to be applied to some documents.
JSONiq update has snapshot semantics, meaning that no side effects occur during the evaluation of the main expression. Instead, after the PUL has been computed, the engine may propagate the changes specified by the PUL to underlying storage (such as a file on disk, or a document store).
A syntactically correct version of the question's example would be:
jsoniq version "1.0";
let $users := {
"name" : "Deadbeat Jim",
"address" : "1 E 161st St, Bronx, NY 10451",
"risk tolerance" : "high"
}
return insert json {"status" : "credit card declined"} into $users
However, in this case, the PUL returned contains changes against a JSON object created on the fly, in memory. The lifetime of this object is only that of the evaluation of the query, so that this program simply has no visible effect.
If the collection
function is in some way mapped to a database in a document store like Couchbase or MongoDB (that is, if the engine is documented and configured to do this), the following query will semantically apply an update to this document store.
jsoniq version "1.0";
let $users := collection("users")[$$.name eq "Jim"]
return insert json {"status" : "credit card declined"} into $users
A copy-modify-return expression (also called transform expression like in XQuery, see other answer on this page) provides a way to apply changes in memory without losing them, and without any persistent storage. It:
- creates a JSON object (as a copy of another), or an XML node, etc
- modifies that object by applying the PUL obtained from the modify expression (important: this has no visible side effects, as only a copy is being modified)
- returns the modified copy.
For advanced users: in this case, the copy clause contains a constructor that builds a fresh object, so the optimizer can actually skip the copying.