modify(
函数用于修改集合中的文档,类似于 SQL 数据库的 UPDATE 语句。它采用搜索条件字符串(SearchConditionStr)作为参数来指定要修改的文档 - 有关 SearchConditionStr 的详细讨论可以在 第 4.3.2 节“Collection.find()” 中找到。SearchConditionStr
)
如果一个或多个文档与搜索条件字符串匹配,则它们将由 modify()
方法之后链接的任何方法修改。它们可以一个接一个地链接,并且可以多次链接
-
set("
:使用表达式或字面量(ExprOrLiteral)表达式表示的值设置与文档路径(DocPath)表达式匹配的元素。DocPath
",ExprOrLiteral
)DocPath 表达式是一个 JSON 路径 表达式,用于标识由
modify()
函数找到的文档中的一个或多个 JSON 元素。请参阅 第 4.3.2 节“Collection.find()” 中有关 JSON 路径 的讨论。如果 DocPath 指定的元素不存在,则将其作为新元素添加到文档中。ExprOrLiteral 指定要为 DocPath 表示的元素设置的值。它可以是以下任何一项
字面量值。例如,10 或“John”。
-
任何 X DevAPI 表达式,包装在
expr()
函数(或 MySQL Shell 和某些连接器的mysql.expr()
)中,因此它不会被视为字面量值。以下是一些示例,但并未涵盖将mysql.expr(表达式)
用于 ExprOrLiteral 的所有可能性另一个 DocPath 从正在修改的文档中选择一个值(例如,
set("favorNums[0]", mysqlx.expr("favorNums[1]"))
,或set("name", mysqlx.expr("$.'last name'"))
。涉及一个或多个 表达式 的函数表达式(例如,
set("favorNums[0]", mysqlx.expr("abs(favorNums[1])"))
。由运算符连接的一个或多个 表达式(例如,
set("favorNums[0]", mysqlx.expr("favorNums[1]+favorNums[2]+favorNums[3]+3"))
,或set("SameValueOrNot", mysqlx.expr("favorNums[1] = favorNums[2]"))
。JSON 文档(例如,
set("Greeting", mysqlx.expr("{'season':'winter', 'phrase': 'Happy Holiday'}"))
注意set("$", mysqlx.expr("
将json_document
")modify()
匹配的所有文档替换为提供的json_document
,但原始的_id
字段除外,该字段在文档创建时设置后便不可更改。 -
unset("
:删除由一个或多个 DocPath 表示的一个或多个字段或数组元素(例如,DocPath
[,DocPath
] ...")unset("name")
,unset("name.'last name'", name.'first name'")
,或unset("favorNums[0]")
)。如果未提供 DocPath,或者 DocPath 为 $(如果要删除整个文档,请改用 remove()),则会返回错误。
警告请注意,当删除多个数组元素时,它们会一个接一个地被删除,因此语句中的相同数组索引可能会引用每个 unset 操作的不同元素。删除数组元素时,请考虑到这一点。例如,对于文档
mysql-js> myColl.find("name = 'Ann'"); { "_id": "00006239f74a0000000000000004", "name": "Ann", "favorNums": [ 1, 2, 3, 4, 5 ] }
以下语句不会像预期的那样删除数组的第一个和第二个元素
mysql-js> myColl.modify("name = 'Ann'").unset("favorNums[0]","favorNums[1]"); Query OK, 1 item affected (0.0038 sec) mysql-js> myColl.find("name = 'Ann'").fields("favorNums"); { "favorNums": [ 2, 4, 5 ] } 1 document in set (0.0007 sec)
相反,它删除了数组的第一个和第三个元素。要删除前两个元素,您可以执行以下操作
mysql-js> myColl.modify("name = 'Ann'").unset("favorNums[0]","favorNums[0]"); Query OK, 1 item affected (0.0108 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql-js > myColl.find("name = 'Ann'").fields("favorNums"); { "favorNums": [ 3, 4, 5 ] } 1 document in set (0.0005 sec)
-
patch(
:对Document
)modify()
匹配的任何文档和作为其参数提供的 JSONDocument
执行合并补丁。该操作遵循由互联网工程任务组(IETF)创建的 JSON 合并补丁的 RFC 7396 规范。下表解释了对字段的操作,该操作取决于两个文档中的字段状态(请注意,这是一个递归操作)表 4.1 JSON 文档字段的补丁合并
原始文档中的字段状态 补丁文档中的字段状态 对原始文档中的字段要执行的操作 任意值 值为 Null 删除字段 值 B 值 A(非 Null) 如果值 A 或 B 是标量,则将值 B 替换为值 A
如果值 A 和 B 都是 JSON 对象,则使用此表中描述的相同规则合并它们(也就是说,递归地将合并应用于 JSON 文档)。
字段不存在 值 A(非 Null) 添加值为 A 的字段 值 C 字段不存在 字段不变 以下是使用
patch()
进行合并的简单示例mysql-js> myColl.find("name = 'John Doe'"); { "DOB": "1970-01-01", "_id": "0000626028c30000000000000002", "name": "John Doe", "Phone": 1234567, "Standing": "Good", "favorNums": { "a": 1, "b":2 } } 1 document in set (0.0009 sec) mysql-js> myColl.modify("name = 'John Doe'") .patch({ name: "Jane Doe", DOB: null, Phone: 9876543, favorNums: { a: 3, b:4 } }); Query OK, 1 item affected (0.0413 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql-js> myColl.find("name = 'Jane Doe'"); { "_id": "0000626028c30000000000000002", "name": "Jane Doe", "Phone": 9876543, "Standing": "Good", "favorNums": { "a": 3, "b": 4 } } 1 document in set (0.0008 sec)
-
arrayInsert(
:将 ExprOrLiteral(请参见上面的解释)插入到 DocPath 标识的位置的数组中,并将数组中任何后续值向右移动。例如:DocPath
,ExprOrLiteral
)arrayInsert("favorNums[1]", 7)
,arrayInsert("favorNums[1]", {even: 2, odd: 3, irrational: 'pi'})
。适用以下规则 -
arrayAppend(
:将 ExprOrLiteral 表示的值附加到 DocPath 标识的数组的末尾。例如,DocPath
,ExprOrLiteral
)arrayAppend("favorNums", 555)
。请注意,如果 DocPath 指向标量或文档值,则该值将自动包装在数组中,并且 ExprOrLiteral 表示的值将添加到该数组中。例如
mysql-js> myColl.find("name='Jane Doe'"); { "_id": "000062b0faf90000000000000001", "name": "Jane Doe", "favorNum": 2 } 1 document in set (0.0011 sec) mysql-js> myColl.modify("name='Jane Doe'").arrayAppend("favorNum",3); Query OK, 1 item affected (0.0094 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql-js> myColl.find("name='Jane Doe'"); { "_id": "000062b0faf90000000000000001", "name": "Jane Doe", "favorNum": [ 2, 3 ] } 1 document in set (0.0006 sec)
以下方法可以链接到上述修改方法,以配置修改
-
sort(
:根据sortCriteriaList
)sortCriteriaList
对要修改的文档的顺序进行排序,sortCriteriaList
是以逗号分隔的列表或
的数组。每个sortCriteria
由组件名称和搜索顺序(sortCriteria
asc
表示升序,desc
表示降序)组成。例如sort('name asc', 'age desc')
sort(['name asc', 'age desc'])
该方法与
limit()
方法结合使用,以确定要修改modify(
匹配的哪些文档。SearchConditionStr
) limit(
:将要修改的文档数量限制为int
)
。当在int
sort()
之后链接时,只修改排序列表中的前int
个文档。
这是一个使用 sort().limit()
限制对文档的修改的示例
mysql-js> myColl.find("name like '%Doe'");
{
"_id": "000062b0faf90000000000000001",
"name": "Jane Doe",
"favorNum": [
2,
3
]
}
{
"_id": "000062b372f80000000000000001",
"name": "Bob Doe",
"favorNum": [
1,
2
]
}
{
"_id": "000062b372f80000000000000002",
"name": "Mark Doe",
"favorNum": [
7,
8
]
}
{
"_id": "000062b372f80000000000000003",
"name": "John Doe",
"favorNum": [
0,
4
]
}
mysql-js> myColl.modify("name like '%Doe'").unset("favorNum").sort("name asc").limit(2);
Query OK, 2 items affected (0.0082 sec)
Rows matched: 2 Changed: 2 Warnings: 0
mysql-js> myColl.find("name like '%Doe'").sort('name asc');
{
"_id": "000062b372f80000000000000001",
"name": "Bob Doe"
}
{
"_id": "000062b0faf90000000000000001",
"name": "Jane Doe"
}
{
"_id": "000062b372f80000000000000003",
"name": "John Doe",
"favorNum": [
0,
4
]
}
{
"_id": "000062b372f80000000000000002",
"name": "Mark Doe",
"favorNum": [
7,
8
]
}
4 documents in set (0.0068 sec)
也支持使用 bind()
进行参数绑定。execute()
函数触发 modify()
操作的实际执行。以下示例说明了 modify()
的用法
MySQL Shell JavaScript 代码
// Use the collection 'my_collection'
var myColl = db.getCollection('my_collection');
// Add a new document to the collection
myColl.add({ name:"John Doe", DOB:"1970-01-01", Phone:1234567, Standing: "Good" }).execute();
// Patch the added document, adding, removing, and changing some fields
myColl.modify("name = 'John Doe'").patch({ name: "Jane Doe", DOB: null, Phone: 9876543, favorNums: [1,2,3,4,5] }).execute();
//Modify fields with different methods
myColl.modify("name like :param").set("Standing", "Bad").bind("param", "J%Doe").execute();
myColl.modify("name like :param").unset("Phone").bind("param", "J%Doe").execute();
myColl.modify("name like :param").arrayInsert("favorNums[1]", 7).bind("param", "J%Doe").execute();
myColl.modify("name like :param").arrayAppend("favorNums", 99).bind("param", "J%Doe").execute();
myColl.modify("name like :param").unset("favorNums[2]").bind("param", "J%Doe").execute();
var doc = myColl.find('name like :param').limit(1).bind('param', 'J%Doe').execute();
print(doc.fetchOne());
/* The output looks like:
{
"Standing": "Bad",
"_id": "0000626718c10000000000000002",
"favorNums": [
1,
7,
3,
4,
5,
99
],
"name": "Jane Doe"
} */
MySQL Shell Python 代码
# Use the collection 'my_collection'
myColl = db.get_collection('my_collection')
# Add a new document to the collection
myColl.add({ "name":"John Doe", "DOB":"1970-01-01", "Phone":1234567, "Standing": "Good" }).execute()
# Patch the added document, adding, removing, and changing some fields
myColl.modify("name = 'John Doe'").patch({ "name": "Jane Doe", "DOB": None, "Phone": 9876543, "favorNums": [1,2,3,4,5] }).execute()
# Modify fields with different methods
myColl.modify("name like :param").set("Standing", "Bad").bind("param", "J%Doe").execute()
myColl.modify("name like :param").unset("Phone").bind("param", "J%Doe").execute()
myColl.modify("name like :param").array_insert("favorNums[1]", 7).bind("param", "J%Doe").execute()
myColl.modify("name like :param").array_append("favorNums", 99).bind("param", "J%Doe").execute()
myColl.modify("name like :param").unset("favorNums[2]").bind("param", "J%Doe").execute()
doc = myColl.find('name like :param').limit(1).bind('param', 'J%Doe').execute()
print(doc.fetch_one())
# The output looks like:
# {"Standing": "Bad", "_id": "0000626718c10000000000000005", "favorNums": [1, 7, 3, 4, 5, 99], "name": "Jane Doe"}
Node.js JavaScript 代码
const mysqlx = require('@mysql/xdevapi');
mysqlx.getSession('mysqlx://127.0.0.1:33060')
.then(session=> {
const collection = session.getSchema('mySchema').getCollection('myCollection');
// Add a new document to the collection
return collection.add({ name:"John Doe", DOB:"1970-01-01", Phone:1234567, Standing: "Good" })
.execute()
// Patch the added document, adding, removing, and changing some fields
.then(()=> {
return collection.modify("name = 'John Doe'")
.patch({ name: "Jane Doe", DOB: null, Phone: 9876543, favorNums: [1,2,3,4,5] })
.execute();
})
// Modify fields with different methods
.then(()=> {
return collection.modify("name like :param")
.set("Standing", "Bad")
.bind("param", "J%Doe")
.execute();
})
.then(()=> {
return collection.modify("name like :param")
.unset("Phone").bind("param", "J%Doe")
.bind("param", "J%Doe")
.execute();
})
.then(()=> {
return collection.modify("name like :param")
.arrayInsert("favorNums[1]", 7)
.bind("param", "J%Doe")
.execute();
})
.then(()=> {
return collection.modify("name like :param")
.arrayAppend("favorNums", 99)
.bind("param", "J%Doe")
.execute();
})
.then(()=> {
return collection.modify("name like :param")
.unset("favorNums[2]")
.bind("param", "J%Doe")
.execute();
})
.then(()=> {
return collection.find('name like :param')
.limit(1).bind('param', 'J%Doe')
.execute();
})
.then(res => {
console.log(res.fetchOne());
/* The output looks like:
{
_id: '00006272fb890000000000000004',
name: 'Jane Doe',
Standing: 'Bad',
favorNums: [ 1, 7, 3, 4, 5, 99 ]
} */
});
});
C# 代码
// Use the collection "my_collection"
var myColl = myDb.GetCollection("my_collection");
// Insert a document
myColl.Add(new { name = "John Doe", DOB = "1970-01-01", Phone = 1234567, Standing = "Good" }).Execute();
//Patch the added document, adding, removing, and changing some fields
myColl.Modify("name = 'John Doe'")
.Patch(new { name = "Jane Doe", DOB = (string)null, Phone = 9876543, favorNums = new[] { 1, 2, 3, 4, 5 } })
.Execute();
//Modify fields with different methods
myColl.Modify("name like :param").Set("Standing", "Bad").Bind("param", "J%Doe").Execute();
myColl.Modify("name like :param").Unset("Phone").Bind("param", "J%Doe").Execute();
myColl.Modify("name like :param").ArrayInsert("favorNums[1]", 7).Bind("param", "J%Doe").Execute();
myColl.Modify("name like :param").ArrayAppend("favorNums", 99).Bind("param", "J%Doe").Execute();
myColl.Modify("name like :param").Unset("favorNums[2]").Bind("param", "J%Doe").Execute();
var docs = myColl.Find("name like :param").Limit(1).Bind("param", "J%Doe").Execute();
Console.WriteLine(docs.FetchOne());
/* The output looks like:
{
"_id": "00006274151a0000000000000004",
"name": "Jane Doe",
"Standing": "Bad",
"favorNums": [
1,
7,
3,
4,
5,
99
]
}
*/
Python 代码
# Use the collection 'my_collection'
my_coll = my_schema.get_collection('my_collection')
# Add a new document to the collection
my_coll.add({ "name":"John Doe", "DOB":"1970-01-01", "Phone":1234567, "Standing": "Good" }).execute()
# Patch the added document, adding, removing, and changing some fields
my_coll.modify("name = 'John Doe'").patch({"name": "Jane Doe", "DOB": None, "Phone": 9876543, "favorNums": [1,2,3,4,5] }).execute()
# Modify fields with different methods
my_coll.modify("name like :param").set("Standing", "Bad").bind("param", "J%Doe").execute()
my_coll.modify("name like :param").unset("Phone").bind("param", "J%Doe").execute()
my_coll.modify("name like :param").array_insert("favorNums[1]", 7).bind("param", "J%Doe").execute()
my_coll.modify("name like :param").array_append("favorNums", 99).bind("param", "J%Doe").execute()
my_coll.modify("name like :param").unset("favorNums[2]").bind("param", "J%Doe").execute()
docs = my_coll.find('name like :param').limit(1).bind('param', 'J%Doe').execute()
print(docs.fetch_one())
# The output looks like:
#{"_id": "0000627ac9ac0000000000000007", "name": "Jane Doe", "Standing": "Bad", "favorNums": [1, 7, 3, 4, 5, 99]}
Java 代码
// Use the collection 'my_collection'
Collection myColl = db.getCollection("my_collection");
// Add a new document to the collection
myColl.add("{ \"name\":\"John Doe\", \"DOB\" : \"1970-01-01\", \"Phone\" : 1234567, \"Standing\" : \"Good\" }").execute();
// Patch the added document, adding, removing, and changing some fields
myColl.modify("name = 'John Doe'").patch("{ \"name\": \"Jane Doe\", \"DOB\" : null, \"Phone\" : 9876543, \"favorNums\" : [1,2,3,4,5] }").execute();
//Modify fields with different methods
myColl.modify("name like :param").set("Standing", "Bad").bind("param", "J%Doe").execute();
myColl.modify("name like :param").unset("Phone").bind("param", "J%Doe").execute();
myColl.modify("name like :param").arrayInsert("favorNums[1]", 7).bind("param", "J%Doe").execute();
myColl.modify("name like :param").arrayAppend("favorNums", 99).bind("param", "J%Doe").execute();
myColl.modify("name like :param").unset("favorNums[2]").bind("param", "J%Doe").execute();
DocResult docs = myColl.find("name like : param").limit(1).bind("param", "J%Doe").execute();
while (docs.hasNext()) {
DbDoc myDoc = docs.next();
System.out.println(myDoc);
}
//The output looks like:
//{"Standing":"Bad","_id":"0000627eadcb0000000000000001","favorNums":[1,7,3,4,5,99],"name":"Jane Doe"}
C++ 代码
Collection myColl = db.getCollection("my_collection");
// Add a new document to the collection
myColl.add(R"({ "name":"John Doe", "DOB" : "1970-01-01", "Phone" : 1234567, "Standing" : "Good" })").execute();
// Patch the added document, adding, removing, and changing some fields
myColl
.modify("name = 'John Doe'")
.patch(R"({
"name": "Jane Doe", "DOB" : null, "Phone" : 9876543, "favorNums" : [1,2,3,4,5]
})")
.execute();
//Modify fields with different methods
myColl.modify("name like :param").set("Standing", "Bad").bind("param", "J%Doe").execute();
myColl.modify("name like :param").unset("Phone").bind("param", "J%Doe").execute();
myColl.modify("name like :param").arrayInsert("favorNums[1]", 7).bind("param", "J%Doe").execute();
myColl.modify("name like :param").arrayAppend("favorNums", 99).bind("param", "J%Doe").execute();
myColl.modify("name like :param").unset("favorNums[2]").bind("param", "J%Doe").execute();
DocResult docs = myColl.find("name like :param").limit(1).bind("param", "J%Doe").execute();
DbDoc myDoc;
while ((myDoc = docs.fetchOne()))
{
cout << myDoc << endl;
}
//The output looks like:
// {"_id": "0000627ea0a80000000000000006", "name": "Jane Doe", "Standing": "Bad", "favorNums": [1, 7, 3, 4, 5, 99]}
另请参阅 CollectionModifyFunction,了解 EBNF 中 add()
的语法。