2013-01-12 22 views
20

Tôi sử dụng mongodb + node.js + mongoose.js ORM backend.Cách xử lý thay đổi "lược đồ" mongodb trong sản xuất

Hãy nói II có một số mảng lồng nhau của các đối tượng mà không lĩnh vực _id

mongoose.Schema({ 
    nested: [{ 
    _id: false, prop: 'string' 
    }] 
}) 

Và sau đó tôi muốn lĩnh vực _id quảng cáo cho tất cả objectds lồng nhau, vì vậy các schema mongoose sẽ

mongoose.Schema({ 
    nested: [{ 
    prop: 'string' 
    }] 
}) 

Sau đó, Tôi nên chạy một số kịch bản để sửa đổi DB sản xuất, phải không? Cách tốt nhất để xử lý thay đổi đó là gì? Công cụ nào (hay cách tiếp cận) nào là tốt nhất để sử dụng để thực hiện thay đổi?

+0

Từ ví dụ bạn đã cung cấp, có vẻ như bạn muốn xóa _id, thay vì thêm nó. Nếu bạn muốn thêm _id, làm cách nào để xác định mỗi _id nên là gì? – Eduardo

+0

Tôi không hiểu bạn. _id: false nói với mongoose không tạo _id cho các đối tượng được mô tả bởi lược đồ, nếu tôi loại bỏ _id: false khỏi trình mô tả lược đồ sẽ tạo ra các tài liệu mới với _id được tạo ra. Những gì tôi hỏi là đúng cách để cư trú tất cả các đối tượng hiện có (mà không có _id) với _ids mới. – WHITECOLOR

+0

các _ids có được hệ thống tạo ra hay không? – Eduardo

Trả lời

12

Một trong những lợi thế đáng kể của cơ sở dữ liệu lược đồ ít hơn là bạn không phải cập nhật toàn bộ cơ sở dữ liệu với bố cục lược đồ mới. Nếu một số tài liệu trong DB không có thông tin cụ thể, thì mã của bạn có thể làm điều thích hợp thay vào đó hoặc chọn để làm bất kỳ điều gì với bản ghi đó.

Tùy chọn khác là lazily cập nhật tài liệu theo yêu cầu - chỉ khi chúng được xem xét lại. Trong trường hợp này, bạn có thể chọn cờ có phiên bản mỗi bản ghi/tài liệu - ban đầu có thể không xuất hiện (và do đó có nghĩa là 'phiên bản 0'). Mặc dù đó là tùy chọn mặc dù. Thay vào đó, mã truy cập cơ sở dữ liệu của bạn tìm kiếm dữ liệu mà nó yêu cầu, và nếu nó không tồn tại, vì nó là thông tin mới, được thêm vào sau khi cập nhật mã, sau đó nó sẽ điền vào kết quả với khả năng tốt nhất của nó.

Ví dụ: chuyển đổi _id:false thành trường MongoId tiêu chuẩn, khi mã được đọc (hoặc được viết lại sau khi cập nhật) và _id:false hiện được đặt, sau đó thực hiện thay đổi và chỉ ghi khi hoàn toàn cần thiết.

+0

Xin lỗi, tôi không hiểu ý bạn là gì với '_id: false'. Tôi thực sự quan tâm. Bạn có thể giải thích nó không? – hgoebl

+0

Ah, tôi chưa đọc nội dung câu hỏi, xin lỗi, đó không phải lỗi của bạn. Nhưng ví dụ với '_id: false' có thể là một chút sai lầm cho toàn bộ câu hỏi. Sẽ rất hay khi có một ví dụ dễ hiểu hơn cho tất cả mọi người và đặc biệt là đối với những người không sử dụng Mongoose. – hgoebl

+1

Làm thế nào điều này sẽ được với các hoạt động như thêm một chỉ số mới: 'patientSchema.index ({patientId: 1, institute: 1}, {unique: true})', trong dev tôi đã phải xóa chỉ mục cũ mà không có '{unique : true} 'để làm cho nó hoạt động –

10

Bạn thực sự phải viết tập lệnh sẽ đi qua bộ sưu tập và thêm trường mới vào từng tài liệu. Tuy nhiên cách chính xác như thế nào bạn sẽ làm điều đó phụ thuộc vào kích thước của DB của bạn và hiệu suất của hệ thống lưu trữ của bạn. Thêm một trường vào tài liệu sẽ thay đổi kích thước của nó và do đó gây ra việc di dời trong hầu hết các trường hợp. Hoạt động này có tác động đến IO và cũng bị ràng buộc bởi nó. Nếu bộ sưu tập của bạn chỉ là một vài nghìn tài liệu, có thể lên tới một trăm nghìn, thì bạn có thể lặp lại nó trong một vòng lặp vì toàn bộ bộ sưu tập có thể phù hợp với bộ nhớ và tất cả IO sẽ xảy ra sau đó. Tuy nhiên, nếu bộ sưu tập vượt xa bộ nhớ có sẵn, thì cách tiếp cận này phức tạp hơn. Chúng tôi thường làm theo các bước tiếp theo trong việc sử dụng sản xuất của MongoDB:

  • mở con trỏ với timeout = False
  • đọc một đoạn văn bản vào bộ nhớ
  • Run cập nhật các truy vấn trên các tài liệu này
  • Ngủ trong một thời gian tới tránh quá tải IO hệ thống phụ và gây tổn thương cho ứng dụng sản xuất
  • Lặp lại cho đến khi thực hiện
  • Đóng con trỏ :)

Kích thước của đoạn văn bản và thời gian ngủ phải được xác định bằng thực nghiệm. Thông thường, bạn muốn tránh QR/QW trong mongostats trong thời gian di chuyển. Đối với các bộ sưu tập lớn hơn trên các ổ đĩa chậm hơn (như EBS trên Amazon), cách tiếp cận an toàn IO này có thể mất từ ​​vài giờ đến vài ngày.

+0

Bạn có ví dụ mã ngắn cho con trỏ không? Tôi đặc biệt quan tâm đến phiên bản JavaScript, vì tôi nghĩ nó không tầm thường, đặc biệt là ngủ một thời gian và không nhận được song song ... – hgoebl

+0

Tôi không có ví dụ về JavaScript, nhưng trong trình điều khiển PyMongo tắt thời gian chờ cho con trỏ được thực hiện bằng cách đơn giản truyền timeout = False để tìm() phương pháp. Tôi nghĩ rằng trình điều khiển JavaScript sẽ có một cái gì đó như thế này. –

Các vấn đề liên quan