4.3.3 Collection.modify()
Функция modify( предназначена для модификации документов в коллекции, подобно оператору UPDATE для базы данных SQL. Она принимает строку условия поиска (SearchConditionStr) в качестве параметра, чтобы указать документы, которые должны быть изменены — подробное обсуждение SearchConditionStr можно найти в разделе 4.3.2 «Collection.find()». SearchConditionStr)
Если одно или несколько документов соответствуют условию поиска, они изменяются с помощью любого из этих методов, которые прицеплены после метода modify(). Их можно цеплять друг за другом и несколько раз:
_idдокумента изменить или удалить с помощью нижеперечисленных методов нельзя.-
Для любого из методов ниже, принимающих выражение DocPath в качестве одного из аргументов, применяются следующие правила:
-
set(": Установите значения элементов, соответствующих выражению пути к документу (DocPath), со значением, представленным выражением или литералом (ExprOrLiteral).DocPath",ExprOrLiteral)Выражение DocPath представляет собой выражение пути JSON, определяющее один или несколько элементов JSON в документах, найденных функцией
modify(). Подробнее о выражениях пути JSON см. в разделе 4.3.2 «Collection.find()». Если элемент, указанный DocPath, не существует, он добавляется в документ в качестве нового элемента.ExprOrLiteral задает значение для элемента, представленного DocPath. Это может быть:
Литеральное значение. Например, 10 или "Иванов".
-
Любое выражение X DevAPI выражения, заключенное в функцию
expr()(илиmysql.expr()для MySQL Shell и некоторых подключений), чтобы оно не воспринималось как литеральное значение. Вот некоторые примеры, которые не исчерпывают все возможности использованияmysql.expr(Expression)для 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() вместо этого, если вы хотите удалить весь документ).
ПредупреждениеОбратите внимание, что при удалении нескольких элементов массива они удаляются по одному, и один и тот же индекс массива в операторе может, следовательно, ссылаться на разные элементы для каждого действия удаления. Учтите это при удалении элементов массива. Например, для документа:
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, переданным в качестве параметра. Операция следует спецификации RFC 7396 для слияния JSON-патчей, разработанной Internet Engineering Task Force (IETF). Следующая таблица объясняет действие над полем, которое зависит от статусов поля в двух документах (обратите внимание, что это рекурсивная операция):Таблица 4.1 Слияние JSON-патчей для полей документа
Таблица 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, что представляет собой либо список, разделенный запятыми, либо массив. КаждыйsortCriteriaсостоит из имени компонента и порядка поиска (sortCriteriaascдля возрастания илиdescдля убывания). Например:sort('name asc', 'age desc')sort(['name asc', 'age desc'])
Данный метод используется совместно с методом
limit()для определения, какие из документов, соответствующих критериямmodify(, подлежат модификации.SearchConditionStr) limit(: Ограничивает количество документов, подлежащих модификации, доint). При использовании послеintsort(), модифицируются только первые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():
# 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"}
Смотрите также CollectionModifyFunction для синтаксиса add() в EBNF.
© 2025 Oracle
Licensed under the GPLv2 License.