2012-02-29 30 views
6

Tôi cần lưu trữ một số dữ liệu về cơ bản chỉ là một loạt các cặp khóa-giá trị của ngày/tháng, trong đó ngày sẽ luôn là duy nhất.MongoDB - Có thể truy vấn bằng khóa mảng kết hợp không?

Tôi muốn để có thể lưu nó như một mảng kết hợp:.

array(
    "2012-02-26" => 5, 
    "2012-02-27" => 2, 
    "2012-02-28" => 17, 
    "2012-02-29" => 4 
) 

nhưng tôi cũng cần để có thể truy vấn số ngày (tức là có được mọi thứ mà ngày> 2012/02/27), và do đó nghi ngờ rằng tôi sẽ cần phải sử dụng một sơ đồ giống như:

array(
    array("date"=>"2012-02-26", "value"=>5), 
    array("date"=>"2012-02-27", "value"=>2), 
    array("date"=>"2012-02-28", "value"=>17), 
    array("date"=>"2012-02-29", "value"=>4), 
) 

Rõ ràng là cựu là rất sạch và súc tích hơn, nhưng tôi sẽ có thể truy vấn nó theo cách mà tôi đang mong muốn, và nếu không có bất kỳ lược đồ nào khác có thể phù hợp hơn?

+0

http://www.php.net/manual/en/mongo.queries.php –

+0

Tôi không lưu trữ ngày ở định dạng đó. Sử dụng thời gian(); chức năng. Nó sẽ làm cho nó dễ dàng hơn để sắp xếp ngày và như vậy. http://php.net/manual/en/function.time.php –

Trả lời

10

Bạn đã mô tả hai phương pháp, hãy để tôi chia nhỏ chúng.

Phương pháp # 1 - Associative Mảng

Các công cụ quan trọng để truy vấn bởi "mảng kết hợp" là các nhà điều hành $exists. Here là chi tiết về toán tử.

Vì vậy, bạn chắc chắn có thể chạy một truy vấn như sau:

db.coll.find({ $exists: { 'field.2012-02-27' } }); 

Dựa trên mô tả của bạn, bạn đang tìm kiếm cho các truy vấn nhiều mà không phù hợp tốt với các nhà điều hành $exists. Phiên bản "mảng kết hợp" cũng khó lập chỉ mục.

Phương pháp # 2 - Mảng các đối tượng

này chắc chắn có tốt hơn chức năng truy vấn:

db.coll.find({ 'field.date': { $gt: '2012-02-27' } }); 

Nó cũng có thể được lập chỉ mục

db.coll.ensureIndex({ 'field.date': 1 }); 

Tuy nhiên, có một thương mại- tắt khi cập nhật. Nếu bạn muốn tăng giá trị cho một ngày cụ thể, bạn phải sử dụng toán tử vị trí khó xử này $. Điều này làm việc cho một mảng các đối tượng, nhưng nó không thành công cho bất kỳ thứ gì có thêm lồng nhau.

Các vấn đề khác

Một vấn đề với một trong những phương pháp này là sự phát triển lâu dài của dữ liệu. Khi bạn mở rộng kích thước đối tượng, nó sẽ chiếm nhiều không gian hơn trên đĩa và trong bộ nhớ. Nếu bạn có một đối tượng với hai năm giá trị của dữ liệu mà toàn bộ mảng 700 mặt hàng sẽ cần phải có trong bộ nhớ để bạn có thể cập nhật dữ liệu cho ngày hôm nay. Điều này có thể không phải là một vấn đề cho dữ liệu cụ thể của bạn, nhưng nó cần được xem xét.

Trong cùng một tĩnh mạch, truy vấn MongoDB luôn trả về đối tượng cấp cao nhất. Một lần nữa, nếu bạn có một loạt 700 mục, bạn sẽ nhận được tất cả chúng cho mỗi tài liệu phù hợp. Có nhiều cách để lọc ra các trường được trả về, nhưng chúng không hoạt động đối với "mảng các đối tượng".

+0

'Nếu bạn có một đối tượng có giá trị dữ liệu trong hai năm thì toàn bộ mảng 700 mục cần phải có trong bộ nhớ để cập nhật dữ liệu cho ngày hôm nay' - nếu tôi sử dụng' $ slice' để xóa một tập hợp con của mảng và '$ push' để nối thêm một mục mới vào một mảng? –

+0

Vì vậy, nó hoạt động để trả lại dữ liệu, nhưng chỉ khi bạn đẩy theo thứ tự ngày tháng. Tuy nhiên, ở phía máy chủ, nó vẫn cần phải kéo toàn bộ đối tượng vào bộ nhớ ngay cả khi nó chỉ truyền cho bạn một phần của nó. –

+0

Ồ đúng, tôi đã không nhận ra điều đó, tôi nhận thấy nó đủ thông minh để chỉ gỡ bỏ tập con được chỉ định. Đó là một chút của một dealbreaker cho dự án hiện tại của tôi, cảm ơn đã dừng tôi nhận được 6 tháng xuống dòng và nhận ra nó sau đó! –

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