MongoDB cập nhật phần tử mảng nếu tồn tại

Nếu bạn đã từng làm việc với MongoDB trước đây thì rất có thể bạn đã lưu trữ các tài liệu phụ trong mảng, đây là một trong nhiều lý do khiến MongoDB tỏa sáng hơn các cơ sở dữ liệu truyền thống khác

cách tiếp cận gật gù

Tuy nhiên, nếu bạn có một tài liệu mà bạn muốn chèn một tài liệu con vào một mảng khi nó không tồn tại, hoặc cập nhật toàn bộ tài liệu trong mảng khi nó tồn tại thì rất có thể bạn sẽ kéo mục đó ra khỏi mảng


// Insert a test item document
db.items.insertOne({
    "_id" : ObjectId("623ded6e1ce9aa98b37ce86a"),
    "items": [
        { "_id": 1, "content": "aaa"},
        { "_id": 2, "content": "bbb"},
        { "_id": 3, "content": "ccc"},
    ]
})

// Pull the array item which we want to update
db.items.updateOne(
    { "_id" : ObjectId("623ded6e1ce9aa98b37ce86a")},
    {
        "$pull": {
            "items": { "_id": 2 }
        }
    }
)

// Push the updated item back in to the array (we're updating content to "zzz")
db.items.updateOne(
    { "_id" : ObjectId("623ded6e1ce9aa98b37ce86a")},
    {
        "$push": {
            "items": {
                "_id": 2, "content": "zzz"
            }
        }
    }
)

// Check final document
db.items.find()
[
  {
    _id: ObjectId("623ded6e1ce9aa98b37ce86a"),
    items: [
      { _id: 1, content: 'aaa' },
      { _id: 3, content: 'ccc' },
      { _id: 2, content: 'zzz' }
    ]
  }
]

Điều này khá ồn ào và nếu ai đó tìm nạp tài liệu trong khi cập nhật nửa chừng thì họ cũng sẽ nhận được chế độ xem tài liệu không nhất quán với mục có id là 2 bị thiếu. Tuy nhiên, chúng tôi có thể khắc phục sự cố với sự không nhất quán bằng cách bắt đầu giao dịch và hoàn thành 2 thao tác cùng nhau

giao dịch

Đoạn mã dưới đây cho thấy 2 hoạt động được bao bọc trong một giao dịch


// Start a session
var session = db.getMongo().startSession( { readPreference: { mode: "primary" } } );

// Start a transaction
session.startTransaction( { readConcern: { level: "local" }, writeConcern: { w: "majority" } } );

try {
    var items = session.getDatabase("test").items;

    // Pull the array item which we want to update
    items.updateOne(
        { "_id" : ObjectId("623ded6e1ce9aa98b37ce86a")},
        {
            "$pull": {
                "items": { "_id": 2 }
            }
        }
    )

    // Push the updated item back in to the array (we're updating content to "zzz")
    items.updateOne(
        { "_id" : ObjectId("623ded6e1ce9aa98b37ce86a")},
        {
            "$push": {
                "items": {
                    "_id": 2, "content": "zzz"
                }
            }
        }
    )

    // Commit the transaction using write concern set at transaction start
    session.commitTransaction();

} catch (error) {
   // Abort transaction on error
   session.abortTransaction();
   throw error;
}

session.endSession();

Đây là một cách tuyệt vời để thực hiện nhiều thao tác trên một tài liệu, tuy nhiên, nó yêu cầu phải có MongoDB 4. 0 đang chạy trong bộ bản sao hoặc MongoDB 4. 2 nếu dữ liệu của bạn được phân vùng trên nhiều phân đoạn

Cập nhật đường ống tổng hợp

Một cách khác là sử dụng thao tác cập nhật với đường dẫn tổng hợp (Điều này cũng yêu cầu MongoDB v4. 2), điều này cho phép một thao tác cập nhật duy nhất mà không cần bất kỳ giao dịch nào

Bản cập nhật bên dưới với quy trình tổng hợp rất giống với thao tác trên, chúng tôi đang sử dụng giai đoạn tổng hợp $addFields để tiếp tục thay thế trên đầu trường myItems

db.items.updateOne(
    { "_id" : ObjectId("6176d58d636041dbac68233c")},
    [
        {
            $addFields: {
                "myItems": {
                    $filter: {
                        input: "$myItems",
                        as: "item",
                        cond: { $ne: [
                                "$$item.id",
                                2
                            ]
                        }
                    }
                }
            }
        },
        {
            $addFields: {
                "myItems": { $concatArrays: [ "$myItems",
                        [
                            {
                                "id": 2,
                                "extraProps": true,
                                "content": "Hello World"
                            }
                        ]
                    ]
                }
            }
        }
    ]
)

Giai đoạn $addFields đầu tiên xóa tài liệu khỏi mảng dựa trên một điều kiện nhất định bằng cách sử dụng toán tử $filter và sau đó giai đoạn $addFields thứ hai sau đó nối thêm tài liệu mới bằng cách sử dụng toán tử $concatArrays

Cách tốt nhất?

Giống như hầu hết mọi thứ trong quá trình phát triển phần mềm, không có cách nào tốt nhất để giải quyết vấn đề, quy trình tổng hợp cập nhật có thể trở nên phức tạp nhưng ít trò chuyện hơn và không yêu cầu giao dịch. Tuy nhiên, cách tiếp cận giao dịch có thể làm cho mã của bạn dễ hiểu hơn, nhưng sau đó có phí giao dịch và cũng yêu cầu một bộ bản sao để phát triển cục bộ

Làm cách nào để cập nhật đối tượng mảng cụ thể trong MongoDB?

Để thực hiện cập nhật trên tất cả các phần tử mảng nhúng của từng tài liệu phù hợp với truy vấn của bạn, hãy sử dụng toán tử vị trí đã lọc $[ ] chỉ định các phần tử mảng phù hợp trong tài liệu cập nhật.

Bản cập nhật MongoDB có chèn nếu không tồn tại không?

Mã cụ thể này kiểm tra xem trường “đội” có giá trị “Ong bắp cày. ” Nếu giá trị này tồn tại thì sẽ không có gì xảy ra. Tuy nhiên, nếu giá trị này không tồn tại thì nó sẽ chèn một tài liệu có các giá trị cụ thể cho các trường “đội”, “điểm” và “đột phá” .

Làm cách nào để nối một phần tử trong mảng từ MongoDB?

Trong MongoDB, toán tử $push được sử dụng để thêm một giá trị đã chỉ định vào một mảng. Nếu trường được đề cập không có trong tài liệu để cập nhật, toán tử $push sẽ thêm trường đó dưới dạng trường mới và bao gồm giá trị được đề cập làm thành phần của nó.

Làm cách nào để cập nhật giá trị mảng trong cầy mangut?

Mongoose cung cấp một số toán tử để cập nhật mảng, chẳng hạn như $addToSet, $push, $pop , v.v. Trong bài viết này, chúng ta sẽ thảo luận về cách sử dụng các toán tử như vậy để thực hiện các thao tác cập nhật trên mảng trong nodejs. Chúng tôi sẽ sử dụng công cụ đưa thư để thực hiện kiểm tra điểm cuối. Bạn có thể tải xuống công cụ đưa thư từ www. người phát thơ. com.