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

Tổng hợp Mongo trong khoảng thời gian

Có một số cách để tiếp cận điều này tùy thuộc vào định dạng đầu ra nào phù hợp nhất với nhu cầu của bạn. Lưu ý chính là với "khung tổng hợp" bản thân nó, bạn thực sự không thể trả về một thứ gì đó "được đúc" dưới dạng ngày tháng, nhưng bạn có thể nhận các giá trị dễ dàng được cấu trúc lại thành một Date đối tượng khi xử lý kết quả trong API của bạn.

Cách tiếp cận đầu tiên là sử dụng "Toán tử Tổng hợp Ngày" có sẵn cho khuôn khổ tổng hợp:

db.collection.aggregate([
    { "$match": {
        "time": { "$gte": startDate, "$lt": endDate }
    }},
    { "$group": {
        "_id": {
            "year": { "$year": "$time" },
            "dayOfYear": { "$dayOfYear": "$time" },
            "hour": { "$hour": "$time" },
            "minute": {
                "$subtract": [
                    { "$minute": "$time" },
                    { "$mod": [ { "$minute": "$time" }, 10 ] }
                ]
            }
        },
        "count": { "$sum": 1 }
    }}
])

Nó trả về một khóa tổng hợp cho _id chứa tất cả các giá trị bạn muốn cho một "ngày". Ngoài ra, nếu luôn luôn chỉ trong vòng "giờ" thì chỉ cần sử dụng phần "phút" và tính ra ngày thực tế dựa trên startDate lựa chọn phạm vi của bạn.

Hoặc bạn có thể chỉ sử dụng "Toán ngày tháng" đơn giản để lấy mili giây kể từ "kỷ nguyên" có thể được cung cấp lại trực tiếp cho một trình tạo ngày tháng.

db.collection.aggregate([
    { "$match": {
        "time": { "$gte": startDate, "$lt": endDate }
    }},
    { "$group": {
        "_id": {
            "$subtract": [
               { "$subtract": [ "$time", new Date(0) ] },
               { "$mod": [
                   { "$subtract": [ "$time", new Date(0) ] },
                   1000 * 60 * 10
               ]}
            ]
        },
        "count": { "$sum": 1 }
    }}
])

Trong mọi trường hợp, những gì bạn không muốn làm là sử dụng $project trước khi thực sự áp dụng $group . Là một "giai đoạn đường ống", $project phải "xoay vòng" mặc dù tất cả các tài liệu đã được chọn và "chuyển đổi" nội dung.

Điều này cần thời gian và thêm vào tổng số thực thi của truy vấn. Bạn chỉ cần đăng ký vào $group trực tiếp như đã được hiển thị.

Hoặc nếu bạn thực sự "thuần túy" về Date đối tượng được trả lại mà không cần xử lý bài đăng, thì bạn luôn có thể sử dụng "mapReduce" , vì các hàm JavaScript thực sự cho phép ghi lại dưới dạng ngày tháng, nhưng chậm hơn khung tổng hợp và tất nhiên là không có phản hồi con trỏ:

db.collection.mapReduce(
   function() {
       var date = new Date(
           this.time.valueOf() 
           - ( this.time.valueOf() % ( 1000 * 60 * 10 ) )
       );
       emit(date,1);
   },
   function(key,values) {
       return Array.sum(values);
   },
   { "out": { "inline": 1 } }
)

Đặt cược tốt nhất của bạn là sử dụng tính năng tổng hợp, vì việc chuyển đổi phản hồi khá dễ dàng:

db.collection.aggregate([
    { "$match": {
        "time": { "$gte": startDate, "$lt": endDate }
    }},
    { "$group": {
        "_id": {
            "year": { "$year": "$time" },
            "dayOfYear": { "$dayOfYear": "$time" },
            "hour": { "$hour": "$time" },
            "minute": {
                "$subtract": [
                    { "$minute": "$time" },
                    { "$mod": [ { "$minute": "$time" }, 10 ] }
                ]
            }
        },
        "count": { "$sum": 1 }
    }}
]).forEach(function(doc) {
    doc._id = new Date(doc._id);
    printjson(doc);
})

Và sau đó bạn có đầu ra phân nhóm khoảng thời gian với Date thực đối tượng.



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Sắp xếp theo trường mảng tối đa, tăng dần hoặc giảm dần

  2. Mongodb, nhóm theo ngày tháng và tính theo giờ

  3. mongoose tổng một giá trị trên tất cả các tài liệu

  4. kết nối mongodb được tạo trong mongolab thông qua ứng dụng java

  5. Sử dụng Jade để lặp lại JSON