Spec-Zone.ru › MySQL Connectors 1.0

4.3.3 Collection.modify()

Функция modify(SearchConditionStr) предназначена для модификации документов в коллекции, подобно оператору UPDATE для базы данных SQL. Она принимает строку условия поиска (SearchConditionStr) в качестве параметра, чтобы указать документы, которые должны быть изменены — подробное обсуждение SearchConditionStr можно найти в разделе 4.3.2 «Collection.find()».

Если одно или несколько документов соответствуют условию поиска, они изменяются с помощью любого из этих методов, которые прицеплены после метода modify(). Их можно цеплять друг за другом и несколько раз:

Примечания
  • _id документа изменить или удалить с помощью нижеперечисленных методов нельзя.

  • Для любого из методов ниже, принимающих выражение DocPath в качестве одного из аргументов, применяются следующие правила:

    • В выражении DocPath имена полей, содержащие пробелы или специальные символы, должны быть заключены в кавычки; например, set("name.'last name'", "Smith"), unset("name.'last%name'")

    • Выражение DocPath не может содержать символы подстановки (ни * ни **).

    • Выражение DocPath не может быть null или пустым.

  • 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(), и JSON Document, переданным в качестве параметра. Операция следует спецификации 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(DocPath, ExprOrLiteral): Вставка ExprOrLiteral (см. объяснения выше) в массив в позиции, определённой DocPath, сдвигая последующие значения в массиве вправо. Например: arrayInsert("favorNums[1]", 7), arrayInsert("favorNums[1]", {even: 2, odd: 3, irrational: 'pi'}). Применяются следующие правила:

    • Если DocPath не указывает на элемент массива, возвращается ошибка.

    • Если DocPath указывает на позицию в массиве за пределами его границ, значение вставляется в конец массива.

  • arrayAppend(DocPath, ExprOrLiteral): Добавление значения, представленного ExprOrLiteral, в конец массива, указанного DocPath. Например, 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. Каждый 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():

Код JavaScript MySQL Shell

// 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"
} */


Код Python MySQL Shell

# 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"}

Код JavaScript Node.js

const mysqlx = require('@mysql/xdevapi');

mysqlx.getSession('mysqlx://localhost: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 для синтаксиса add() в EBNF.

© 2025 Oracle
Licensed under the GPLv2 License.
https://docs.oracle.com/cd/E17952_01/x-devapi-userguide-en/collection-modify.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API