MongoDB đẩy và kéo cùng một bản cập nhật

Tôi có một tài liệu có 2 mảng, tôi muốn di chuyển một phần tử từ mảng này sang mảng khác, tôi đã thử điều này trên bàn điều khiển và nó hoạt động

db.examplecol.update({_id: ObjectId("5056b4b2b9f53a21385076c5")} , {'$pull':{setA:3}, '$push':   {setB:3}})

Nhưng tôi chưa thấy một ví dụ nào về 2 bản cập nhật trong một lệnh. Câu hỏi của tôi là nếu đây là một hoạt động nguyên tử?

- stackoverflow. com

ghi bàn. 6

câu trả lời được chấp nhận

Dựa trên tài liệu Hoạt động nguyên tử của MongoDB và vì hoạt động của bạn nằm trên một tài liệu duy nhất nên hoạt động phải là hoạt động nguyên tử. Bạn nên đảm bảo rằng bạn đang sử dụng ghi nhật ký, vì vậy nếu nguồn điện bị rút nửa chừng trong quá trình cập nhật của bạn, thì MongoDB sẽ khôi phục về trạng thái tốt, đã biết trước khi cập nhật

Tài liệu có một mảng (

{
  "_id": "jcLh4exkHL7KsfuKB",
    "device": {
      "mac": 1,
      "sds": 1000,
      "ids": 12,
      "lvl": 85,
      "sde": [
        {
          "mType": 0,
          "mTs": 1449273600020,
          "pre": 50,
          "hum": 54,
          "temp": 70
        },
        {
          "mType": 0,
          "mTs": 1449273600030,
          "pre": 49,
          "hum": 53,
          "temp": 75
        }
      ],
      "iType": 0,
      "iTs": 1449273600020,
      "mCount": 15,
      "fCount": 500
   }
}
6) cần phát triển khi có thêm dữ liệu cảm biến, nhưng các trường khác chỉ cần được cập nhật, chẳng hạn như thế này (hình 2)

{
  "_id": "jcLh4exkHL7KsfuKB",
    "device": {
      "mac": 1,
      "sds": 1000,
      "ids": 12,
      "lvl": 85,
      "sde": [
        {
          "mType": 0,
          "mTs": 1449273600020,
          "pre": 50,
          "hum": 54,
          "temp": 70
        },
        {
          "mType": 0,
          "mTs": 1449273600030,
          "pre": 49,
          "hum": 53,
          "temp": 75
        }
      ],
      "iType": 0,
      "iTs": 1449273600020,
      "mCount": 15,
      "fCount": 500
   }
}

Vấn đề là tôi chỉ có thể cập nhật ở cấp độ

{
  "_id": "jcLh4exkHL7KsfuKB",
    "device": {
      "mac": 1,
      "sds": 1000,
      "ids": 12,
      "lvl": 85,
      "sde": [
        {
          "mType": 0,
          "mTs": 1449273600020,
          "pre": 50,
          "hum": 54,
          "temp": 70
        },
        {
          "mType": 0,
          "mTs": 1449273600030,
          "pre": 49,
          "hum": 53,
          "temp": 75
        }
      ],
      "iType": 0,
      "iTs": 1449273600020,
      "mCount": 15,
      "fCount": 500
   }
}
7 hoặc cấp độ
{
  "_id": "jcLh4exkHL7KsfuKB",
    "device": {
      "mac": 1,
      "sds": 1000,
      "ids": 12,
      "lvl": 85,
      "sde": [
        {
          "mType": 0,
          "mTs": 1449273600020,
          "pre": 50,
          "hum": 54,
          "temp": 70
        },
        {
          "mType": 0,
          "mTs": 1449273600030,
          "pre": 49,
          "hum": 53,
          "temp": 75
        }
      ],
      "iType": 0,
      "iTs": 1449273600020,
      "mCount": 15,
      "fCount": 500
   }
}
8 chứ không thể cập nhật cả hai. Tôi không gặp bất kỳ lỗi nào, quá trình cập nhật chỉ đơn giản là 'hoàn tất'

Có, bạn có thể sử dụng kéo và thêm cùng lúc với toán tử $addToSet và $pull. Trước tiên chúng ta hãy tạo một bộ sưu tập với các tài liệu

> db.pullAndAddToSetDemo.insertOne({StudentScores : [78, 89, 90]}
.. );
{
   "acknowledged" : true,
   "insertedId" : ObjectId("5c9a797e15e86fd1496b38af")
}

Sau đây là truy vấn để hiển thị tất cả các tài liệu từ một bộ sưu tập với sự trợ giúp của phương thức find()

> db.pullAndAddToSetDemo.find().pretty();

Điều này sẽ tạo ra đầu ra sau

{
   "_id" : ObjectId("5c9a797e15e86fd1496b38af"),
   "StudentScores" : [
      78,
      89,
      90
   ]
}

Sau đây là truy vấn để kéo và thêm vào cùng một lúc trong MongoDB

> var addAndPull = db.pullAndAddToSetDemo.initializeOrderedBulkOp();
> addAndPull.find({ "StudentScores": 89 }).updateOne({ "$addToSet": { "StudentScores": 99 } });
> addAndPull.find({ "StudentScores": 90 }).updateOne({ "$pull": { "StudentScores": 90 } });
> addAndPull.execute();

Điều này sẽ tạo ra đầu ra sau

BulkWriteResult({
   "writeErrors" : [ ],
   "writeConcernErrors" : [ ],
   "nInserted" : 0,
   "nUpserted" : 0,
   "nMatched" : 2,
   "nModified" : 2,
   "nRemoved" : 0,
   "upserted" : [ ]
})

Hãy để chúng tôi kiểm tra tài liệu một lần nữa từ bộ sưu tập. Sau đây là truy vấn

> db.pullAndAddToSetDemo.find().pretty();

Điều này sẽ tạo ra đầu ra sau

________số 8

MongoDB đẩy và kéo cùng một bản cập nhật


MongoDB đẩy và kéo cùng một bản cập nhật

$push là một toán tử cập nhật trong MongoDB để thêm giá trị vào một mảng. Ngược lại, toán tử $set được sử dụng để cập nhật giá trị của một trường hiện có trong tài liệu

Trong hướng dẫn ngắn này, chúng tôi sẽ giới thiệu cách thực hiện các thao tác $push và $set cùng nhau trong một truy vấn cập nhật duy nhất

2. Khởi tạo cơ sở dữ liệu

Trước khi chúng tôi tiếp tục thực hiện nhiều thao tác cập nhật, trước tiên chúng tôi cần thiết lập cơ sở dữ liệu baeldung và nhãn hiệu thu thập mẫu

use baeldung;
db.createCollection(marks);

Hãy chèn một vài tài liệu vào các dấu sưu tập bằng cách sử dụng phương thức insertMany của MongoDB

{
  "_id": "jcLh4exkHL7KsfuKB",
    "device": {
      "mac": 1,
      "sds": 1000,
      "ids": 12,
      "lvl": 85,
      "sde": [
        {
          "mType": 0,
          "mTs": 1449273600020,
          "pre": 50,
          "hum": 54,
          "temp": 70
        },
        {
          "mType": 0,
          "mTs": 1449273600030,
          "pre": 49,
          "hum": 53,
          "temp": 75
        }
      ],
      "iType": 0,
      "iTs": 1449273600020,
      "mCount": 15,
      "fCount": 500
   }
}
0

Khi chèn thành công, truy vấn trên sẽ trả về phản hồi sau

{
  "_id": "jcLh4exkHL7KsfuKB",
    "device": {
      "mac": 1,
      "sds": 1000,
      "ids": 12,
      "lvl": 85,
      "sde": [
        {
          "mType": 0,
          "mTs": 1449273600020,
          "pre": 50,
          "hum": 54,
          "temp": 70
        },
        {
          "mType": 0,
          "mTs": 1449273600030,
          "pre": 49,
          "hum": 53,
          "temp": 75
        }
      ],
      "iType": 0,
      "iTs": 1449273600020,
      "mCount": 15,
      "fCount": 500
   }
}
1

Cho đến nay, chúng tôi đã chèn thành công một số tài liệu mẫu vào bộ sưu tập nhãn hiệu

3. Hiểu vấn đề

Để hiểu rõ vấn đề, trước tiên chúng ta hãy tìm hiểu tài liệu mà chúng ta vừa đưa vào. Nó bao gồm thông tin chi tiết về sinh viên và điểm họ đạt được trong các môn học khác nhau. Tổng điểm là tổng điểm đạt được ở các môn học khác nhau

Hãy xem xét một tình huống mà chúng tôi muốn thêm một chủ đề mới trong mảng chủ đề Chi tiết. Để làm cho dữ liệu nhất quán, chúng tôi cũng cần cập nhật trường TotalMarks

Trong MongoDB, trước tiên, chúng ta sẽ thêm chủ thể mới vào mảng bằng cách sử dụng toán tử $push. Sau đó, chúng ta sẽ đặt trường totalMarks thành một giá trị cụ thể bằng cách sử dụng toán tử $set

Cả hai thao tác này đều có thể được thực hiện riêng lẻ bằng cách sử dụng toán tử $push và $set tương ứng. Nhưng chúng ta có thể viết truy vấn MongoDB để thực hiện cả hai thao tác cùng nhau

4. Sử dụng truy vấn Shell MongoDB

Trong MongoDB, chúng ta có thể cập nhật nhiều trường của tài liệu bằng các toán tử cập nhật khác nhau. Ở đây, chúng ta sẽ sử dụng đồng thời cả hai toán tử $push và $set trong truy vấn updateOne

Hãy xem ví dụ có chứa cả hai toán tử $push và $set cùng nhau

{
  "_id": "jcLh4exkHL7KsfuKB",
    "device": {
      "mac": 1,
      "sds": 1000,
      "ids": 12,
      "lvl": 85,
      "sde": [
        {
          "mType": 0,
          "mTs": 1449273600020,
          "pre": 50,
          "hum": 54,
          "temp": 70
        },
        {
          "mType": 0,
          "mTs": 1449273600030,
          "pre": 49,
          "hum": 53,
          "temp": 75
        }
      ],
      "iType": 0,
      "iTs": 1449273600020,
      "mCount": 15,
      "fCount": 500
   }
}
2

Ở đây, trong truy vấn trên, chúng tôi đã thêm truy vấn bộ lọc dựa trên studentId. Khi chúng tôi nhận được tài liệu đã lọc, chúng tôi sẽ cập nhật totalMarks bằng cách sử dụng toán tử $set. Ngoài ra, chúng tôi chèn dữ liệu chủ đề mới vào mảng chủ đề Chi tiết bằng cách sử dụng toán tử $push

Kết quả là, truy vấn trên sẽ trả về đầu ra sau

{
  "_id": "jcLh4exkHL7KsfuKB",
    "device": {
      "mac": 1,
      "sds": 1000,
      "ids": 12,
      "lvl": 85,
      "sde": [
        {
          "mType": 0,
          "mTs": 1449273600020,
          "pre": 50,
          "hum": 54,
          "temp": 70
        },
        {
          "mType": 0,
          "mTs": 1449273600030,
          "pre": 49,
          "hum": 53,
          "temp": 75
        }
      ],
      "iType": 0,
      "iTs": 1449273600020,
      "mCount": 15,
      "fCount": 500
   }
}
3

Tại đây, MatchedCount chứa số lượng tài liệu phù hợp với bộ lọc, trong khi ModifiedCount chứa số lượng tài liệu đã sửa đổi

5. Mã trình điều khiển Java

Cho đến giờ, chúng ta đã thảo luận về truy vấn shell mongo để sử dụng toán tử $push và $set cùng nhau. Ở đây, chúng ta sẽ học cách triển khai tương tự bằng cách sử dụng mã trình điều khiển Java

Trước khi tiếp tục, trước tiên hãy kết nối với DB và bộ sưu tập cần thiết

{
  "_id": "jcLh4exkHL7KsfuKB",
    "device": {
      "mac": 1,
      "sds": 1000,
      "ids": 12,
      "lvl": 85,
      "sde": [
        {
          "mType": 0,
          "mTs": 1449273600020,
          "pre": 50,
          "hum": 54,
          "temp": 70
        },
        {
          "mType": 0,
          "mTs": 1449273600030,
          "pre": 49,
          "hum": 53,
          "temp": 75
        }
      ],
      "iType": 0,
      "iTs": 1449273600020,
      "mCount": 15,
      "fCount": 500
   }
}
4

Ở đây, chúng tôi đang kết nối với MongoDB, đang chạy ở cổng mặc định cổng 27017 trên localhost

Bây giờ chúng ta hãy xem mã trình điều khiển Java

{
  "_id": "jcLh4exkHL7KsfuKB",
    "device": {
      "mac": 1,
      "sds": 1000,
      "ids": 12,
      "lvl": 85,
      "sde": [
        {
          "mType": 0,
          "mTs": 1449273600020,
          "pre": 50,
          "hum": 54,
          "temp": 70
        },
        {
          "mType": 0,
          "mTs": 1449273600030,
          "pre": 49,
          "hum": 53,
          "temp": 75
        }
      ],
      "iType": 0,
      "iTs": 1449273600020,
      "mCount": 15,
      "fCount": 500
   }
}
5

Trong đoạn mã này, chúng tôi đã sử dụng phương thức updateOne, phương thức này chỉ cập nhật một tài liệu duy nhất dựa trên bộ lọc studentId được áp dụng 1023. Sau đó, chúng tôi đã sử dụng Bản cập nhật. kết hợp để thực hiện nhiều thao tác trong một cuộc gọi. Trường totalMarks sẽ được cập nhật thành 170 và một chủ đề tài liệu mớiDữ liệu sẽ được đẩy vào trường mảng “subjectDetails”

6. Phần kết luận

Trong bài viết này, chúng ta đã hiểu trường hợp sử dụng của việc áp dụng nhiều thao tác cùng nhau trong một truy vấn MongoDB duy nhất. Hơn nữa, chúng tôi đã thực hiện tương tự bằng cách sử dụng truy vấn trình bao MongoDB và mã trình điều khiển Java

Chúng ta có thể sử dụng $push và $set cùng nhau trong MongoDB không?

Cả hai thao tác này đều có thể được thực hiện riêng lẻ bằng toán tử $push và $set tương ứng. Nhưng chúng ta có thể viết truy vấn MongoDB để thực hiện cả hai thao tác cùng nhau .

Sự khác biệt giữa đẩy và đặt trong MongoDB là gì?

$push — Hướng dẫn sử dụng MongoDB . Đối với $set, bạn có thể thiết lập một phần tử cụ thể trong mảng . Đối với $push, nó sẽ luôn ở cuối. Xin lưu ý rằng tôi đã phát hiện ra một số hành vi đặc biệt ở trên khi viết bài đăng này, vì vậy có thể tồn tại nhiều hơn nữa.

Làm cách nào để sử dụng $push trong MongoDB?

Nếu trường không có trong tài liệu cần cập nhật, $push sẽ thêm trường mảng có giá trị làm thành phần của nó . Nếu trường không phải là một mảng, hoạt động sẽ thất bại. Nếu giá trị là một mảng, $push sẽ thêm toàn bộ mảng dưới dạng một phần tử. Để thêm riêng từng phần tử của giá trị, hãy sử dụng công cụ sửa đổi $each với $push.

Làm cách nào để đẩy nhiều giá trị trong mảng trong MongoDB?

Chức năng của toán tử $push có thể được mở rộng hơn nữa bằng cách sử dụng các công cụ sửa đổi sau. mỗi $. Công cụ sửa đổi $each được sử dụng để nối nhiều giá trị vào một mảng. Nếu toán tử $each không được chỉ định, tất cả các giá trị trong toán tử $push sẽ được thêm dưới dạng một mục vào trường mảng trong tài liệu