2012-02-10 35 views
17

Tôi muốn thêm trường mới vào bộ sưu tập, với giá trị của trường mới được đặt thành giá trị của trường hiện tại.Thêm trường mới vào bộ sưu tập có giá trị của trường hiện tại

Cụ thể, tôi muốn đi từ này:

# db.foo.findOne() 
    { 
     "_id"  : ObjectId("4f25c828eb60261eab000000"), 
     "created" : ISODate("2012-01-29T16:28:56.232Z"), 
     "..."  : ... 
    } 

này:

# db.foo.findOne() 
    { 
     "_id"  : ObjectId("4f25c828eb60261eab000000"), 
     "created" : ISODate("2012-01-29T16:28:56.232Z"), 
     "event_ts" : ISODate("2012-01-29T16:28:56.232Z"), #same as created 
     "..."  : ... 
    } 

(văn bản mới trong bộ sưu tập này sẽ không tất cả đều có khả năng dự phòng đặc biệt này, nhưng tôi muốn để làm điều này cho các tài liệu hiện có của tôi)

+0

Vì vậy, đây là điều bạn cần làm một lần? – ggreiner

+0

đúng, chỉ cần thực hiện một lần để chuẩn bị dữ liệu này – Purrell

Trả lời

38
function addEventTsField(){ 
    db.foo.find().forEach(function(doc){ 
     db.foo.update({_id:doc._id}, {$set:{"event_ts":doc.created}}); 
    }); 
} 

Run từ giao diện điều khiển:

addEventTsField(); 
+2

Mặc dù không phải là một hoạt động nguyên tử. Đây là hai hoạt động riêng biệt với khả năng thay đổi dữ liệu giữa ở giữa. (mặc dù anh ấy có thể an toàn trong trường hợp của mình vì có vẻ như anh ấy đang làm điều đó một lần, ngoại tuyến) – UpTheCreek

2

Không, điều đó là không thể. Chỉ có hai bước mà bạn có thể biết:

  1. Nạp tài liệu, đọc trường. (Bạn có thể tải chỉ specific fields: _id, và created trong trường hợp của bạn nếu hiệu suất là một vấn đề)
  2. cập nhật nguyên tử của tài liệu (đặt event_ts bằng cách sử dụng tải created lĩnh vực)
+0

Ngay cả với một cái gì đó với db.foo.find(). ForEach()? – Purrell

+1

@Purrell: 'forEach' thực sự tải tất cả các tài liệu đã tìm thấy, và nó trở thành hai bước cập nhật ... –

-1

vì mã của bạn đã biết cách xử lý event_ts tại sao bạn cần sao chép dữ liệu? bạn có thể đổi tên trường thay vì:

{ $rename : { old_field_name : new_field_name } } 

Xem http://www.mongodb.org/display/DOCS/Updating

+4

Bạn đang tạo một giả định, rằng 'được tạo' cũng không cần thiết trong tài liệu. – Purrell

-1

Nếu nó là một điều một thời gian để làm, không có vấn đề lớn của nó. Chạy một truy vấn như "db.foo.find();" trong khoang mongo của bạn và dán toàn bộ đầu ra vào một trình soạn thảo như Textpad hoặc văn bản tuyệt vời, hãy làm một khối cột (Trong văn bản tuyệt vời, đó là Ctrl + scroll wheel click & Kéo),, dán nó sẽ mở rộng sang một trường khác, đổi tên mới dán cột như bạn muốn nó, sau khi thực hiện, làm một regex để chỉ cần chỉnh sửa toàn bộ bó là "^" với "db.foo.insert ({" và tại "$" là "});"

Nó giống như các bước sau đây.

  1. Bạn dán đầu ra như { 'field1': giá trị, 'field2': value2, 'field3': VALUE4};
    1. sao chép tập hợp cuối cùng và mở rộng bằng cách sử dụng khối cột trình chỉnh sửa {'field1': value, 'field2': value2, 'field3': value4};
    2. Bây giờ, hãy chèn các từ thích hợp để làm cho nó trông giống như một lệnh cho mongo db.foo.insert ({'field1': value, 'field2': value2, 'field3': value4});
    3. Bây giờ sao chép tất cả và dán nó vào vỏ mongo của bạn mà sẽ chỉ làm toàn bộ điều cho bạn như bạn muốn. Kiểm tra nó một lần và làm lại toàn bộ điều ngay sau khi bạn dọn dẹp bộ sưu tập nếu không nó sẽ chèn bản sao. Cũng loại bỏ các trường "_id" trong đầu ra vì nó sẽ xung đột khi bạn cố chèn lại !!

Bây giờ, mỗi dòng trong trình soạn thảo của bạn hiển thị một lệnh Mongo hợp lệ có thể được dán vào vỏ của mình để chèn một tài liệu mới vào bộ sưu tập của bạn. vì vậy hãy kiểm tra nó một lần và nó hoạt động tốt, làm sạch toàn bộ bộ sưu tập của bạn như "db.foo.remove ({});" và dán toàn bộ lệnh từ trình chỉnh sửa sẽ thực hiện nó bằng một cú hích.

Có thể khó khăn khi bạn thử lần đầu tiên, nhưng nếu bạn làm đúng, đó sẽ là một điều tiện lợi để bạn có thể làm việc bất cứ khi nào bạn muốn .... !!

+0

Câu trả lời này thậm chí không có ý nghĩa, vì nó rất dễ bị lỗi, không thể tự động, không thể kiểm tra, không thể viết kịch bản ... Tại sao bạn lại muốn thực hiện thao tác này trong trình chỉnh sửa, khi nó có thể được thực hiện dễ dàng như vậy với một hàm đơn giản và forEach()? –

+0

Ngoài ra -1 vì nó yêu cầu 'db.foo.remove ({})' ở giữa hoạt động, điều này sẽ làm hỏng mọi thứ mong đợi dữ liệu hiện có vẫn còn ở đó. – David

+0

Câu hỏi đã được đăng với ý định đó là một công việc lâu dài. Ngoài ra, thực hiện nó trong trình chỉnh sửa giúp dễ dàng chỉnh sửa những gì cần phải chỉnh sửa, những gì cần được nhận xét hoặc những gì cần xóa. Tất nhiên, giải pháp sử dụng foreach tốt hơn, điều này cũng không quá tệ vì nó rất tiện dụng khi chúng ta đang thử nghiệm trong đó chúng ta cần chèn dữ liệu khá thường xuyên, loại bỏ chúng, thêm chúng lại với vài thay đổi ở đây. vv, Nó cũng có thể được tự động hóa khi bạn chỉ chạy cùng một tập lệnh trong dòng lệnh. – Param

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