MongoDB
 sql >> Cơ Sở Dữ Liệu >  >> NoSQL >> MongoDB

MongoDB - $ set để cập nhật hoặc đẩy phần tử Array

Trên thực tế, thực hiện những gì có vẻ như bạn nói rằng bạn đang làm không phải là một thao tác đơn lẻ, nhưng tôi sẽ hướng dẫn chi tiết các phần cần thiết để thực hiện việc này hoặc đề cập đến các tình huống có thể xảy ra khác.

Những gì bạn đang tìm kiếm một phần là $ vị trí nhà điều hành. Bạn cần một phần của truy vấn để "tìm" phần tử của mảng mà bạn muốn.

db.products.update(
    { 
        "_id": ObjectId("536c55bf9c8fb24c21000095"),
        "recentviews.viewedby": "abc"
    },
    { 
        "$set": { 
            "recentviews.$.vieweddate": ISODate("2014-05-09T04:12:47.907Z")
        }
    }
)

Vì vậy, $ là viết tắt của vị trí phù hợp trong mảng để phần cập nhật biết mục nào trong mảng cần cập nhật. Bạn có thể truy cập các trường riêng lẻ của tài liệu trong mảng hoặc chỉ cần chỉ định toàn bộ tài liệu để cập nhật tại vị trí đó.

db.products.update(
    { 
        "_id": ObjectId("536c55bf9c8fb24c21000095"),
        "recentviews.viewedby": "abc"
    },
    { 
        "$set": { 
            "recentviews.$": {
                 "viewedby": "abc",
                 "vieweddate": ISODate("2014-05-09T04:12:47.907Z")
        }
    }
)

Nếu trên thực tế, các trường không thay đổi và bạn chỉ muốn chèn một phần tử mảng mới nếu không có cùng một phần tử chính xác, thì bạn có thể sử dụng $addToSet

db.products.update(
    { 
        "_id": ObjectId("536c55bf9c8fb24c21000095"),
        "recentviews.viewedby": "abc"
    },
    { 
        $addToSet:{ 
            "recentviews": {
                 "viewedby": "abc",
                 "vieweddate": ISODate("2014-05-09T04:12:47.907Z")
        }
    }
)

Tuy nhiên, nếu bạn chỉ đang tìm kiếm "đẩy" đến một mảng bằng một giá trị khóa riêng nếu điều đó không tồn tại thì bạn cần thực hiện thêm một số xử lý thủ công, bằng cách trước tiên xem liệu phần tử trong mảng có tồn tại hay không và sau đó thực hiện $push tuyên bố nơi nó không.

Bạn nhận được một số trợ giúp từ các phương pháp mongoose khi thực hiện việc này bằng cách theo dõi số lượng tài liệu bị ảnh hưởng bởi bản cập nhật:

Product.update(
    { 
        "_id": ObjectId("536c55bf9c8fb24c21000095"),
        "recentviews.viewedby": "abc"
    },
    { 
        "$set": { 
            "recentviews.$": {
                 "viewedby": "abc",
                 "vieweddate": ISODate("2014-05-09T04:12:47.907Z")
        }
    },
    function(err,numAffected) {

        if (numAffected == 0) {
            // Document not updated so you can push onto the array
            Product.update(
                { 
                    "_id": ObjectId("536c55bf9c8fb24c21000095")
                },
                { 
                    "$push": { 
                        "recentviews": {
                            "viewedby": "abc",
                            "vieweddate": ISODate("2014-05-09T04:12:47.907Z")
                        }
                    }
                },
                function(err,numAffected) {

                }
            );
        }            

    }
);

Lời cảnh báo duy nhất ở đây là có một chút thay đổi về triển khai trong các thông báo writeConcern từ MongoDB 2.6 sang các phiên bản trước đó. Hiện tại, không chắc về cách API mongoose thực sự triển khai trả về numAffected đối số trong lệnh gọi lại, sự khác biệt có thể có ý nghĩa gì đó.

Trong các phiên bản trước, ngay cả khi dữ liệu bạn gửi trong bản cập nhật ban đầu khớp chính xác với một phần tử hiện có và không có thay đổi thực sự nào được yêu cầu thì số tiền "đã sửa đổi" sẽ được trả lại dưới dạng 1 mặc dù không có gì thực sự được cập nhật.

Từ MongoDB 2.6, phản hồi về mối quan tâm ghi có hai phần. Một phần hiển thị tài liệu đã sửa đổi và phần kia hiển thị khớp. Vì vậy, trong khi kết quả khớp sẽ được trả về bởi phần truy vấn khớp với một phần tử hiện có, số lượng tài liệu được sửa đổi thực tế sẽ trả về dưới dạng 0 nếu thực tế thì không cần thay đổi.

Vì vậy, tùy thuộc vào cách số trả về thực sự được triển khai trong mongoose, có thể thực sự an toàn hơn khi sử dụng $addToSet trên bản cập nhật bên trong đó để đảm bảo rằng nếu lý do không có tài liệu bị ảnh hưởng không chỉ là do phần tử chính xác đã tồn tại.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Không thể lấy thuộc tính từ đối tượng mongoose

  2. Cách giám sát MongoDB với Prometheus &ClusterControl

  3. Lược đồ đúng MongoDB cho dữ liệu tổng hợp

  4. Tạo chỉ mục văn bản đa ngôn ngữ trong MongoDB

  5. MongoDB $ min