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

Tổng hợp Mongodb theo Ngày rồi Giờ

Về cơ bản, những gì bạn muốn là một nhóm kép, nhưng bạn không lấy lại được toàn bộ đối tượng ngày bằng cách sử dụng toán tử tổng hợp ngày , chỉ những phần có liên quan:

db.collection.aggregate([
    { "$group": {
        "_id": {
            "customerId": "$customerId",
            "day": { "$dayOfYear": "$startTime" },
            "hour": { "$hour": "$startTime" }
        },
        "pings": { "$sum": "$ping" },
        "links": { "$sum": "$link" }
    }},
    { "$group": {
       "_id": {
           "customerId": "$_id.customerId",
           "day": "$_id.day"
       },
       "hours": { 
           "$push": { 
               "hour": "$_id.hour",
               "pings": "$pings",
               "links": "$links"
           }
       }
    }}
])

Đôi $group cung cấp cho bạn định dạng bạn muốn bằng cách đặt các kết quả vào một mảng mỗi ngày. Một tài liệu trong mẫu, nhưng về cơ bản bạn sẽ nhận được kết quả như sau:

{
    "_id" : {
            "customerId" : 123,
            "day" : 365
    },
    "hours" : [
            {
                    "hour" : 10,
                    "pings" : 2,
                    "links" : 3
            }
    ]
}

Nếu bạn thấy kết quả của toán tử ngày khó xử lý hoặc muốn có kết quả "chuyển qua" đơn giản hóa cho các đối tượng ngày, thì bạn có thể truyền dưới dạng dấu thời gian kỷ nguyên thay thế:

db.collection.aggregate([
    { "$group": {
        "_id": {
            "customerId": "$customerId",
            "day": {
               "$subtract": [
                   { "$subtract": [ "$startTime", new Date("1970-01-01") ] },
                   {
                       "$mod": [
                           { "$subtract": [ "$startTime", new Date("1970-01-01") ] },
                           1000*60*60*24   
                       ]
                   }
               ]
            },
            "hour": {
               "$subtract": [
                   { "$subtract": [ "$startTime", new Date("1970-01-01") ] },
                   {
                       "$mod": [
                           { "$subtract": [ "$startTime", new Date("1970-01-01") ] },
                           1000*60*60   
                       ]
                   }
               ]
            }
        },
        "pings": { "$sum": "$ping" },
        "links": { "$sum": "$link" }
    }},
    { "$group": {
       "_id": {
           "customerId": "$_id.customerId",
           "day": "$_id.day"
       },
       "hours": { 
           "$push": { 
               "hour": "$_id.hour",
               "pings": "$pings",
               "links": "$links"
           }
       }
    }}
])

Bí quyết trong đó là khi bạn $subtract một đối tượng ngày từ một đối tượng khác, kết quả là bạn nhận lại giá trị "kỷ nguyên". Trong trường hợp này, chúng tôi sử dụng ngày bắt đầu "kỷ nguyên" để nhận toàn bộ giá trị dấu thời gian và chỉ cung cấp "toán ngày" để sửa thời gian theo khoảng thời gian được yêu cầu. Vì vậy, kết quả:

{
    "_id" : {
            "customerId" : 123,
            "day" : NumberLong("1419984000000")
    },
    "hours" : [
            {
                    "hour" : NumberLong("1420020000000"),
                    "pings" : 2,
                    "links" : 3
            }
    ]
}

Điều nào có thể dễ chịu hơn đối với bạn so với những gì mà các nhà khai thác ngày cung cấp do đó tùy thuộc vào nhu cầu của bạn.

Bạn cũng có thể thêm một chút viết tắt cho điều này với MongoDB 2.6 qua $let toán tử cho phép bạn khai báo "biến" cho các hoạt động trong phạm vi:

db.event.aggregate([
    { "$group": {
        "_id": {
            "$let": {
                "vars": { 
                   "date": { "$subtract": [ "$startTime", new Date("1970-01-01") ] },
                   "day": 1000*60*60*24,
                   "hour": 1000*60*60
                },
                "in": {
                    "customerId": "$customerId",
                    "day": {
                        "$subtract": [
                            "$$date",
                            { "$mod": [ "$$date", "$$day" ] }
                         ]
                    },
                    "hour": {
                        "$subtract": [
                            "$$date",
                            { "$mod": [ "$$date", "$$hour" ] }
                         ]
                    }
                }
            }
        },
        "pings": { "$sum": "$ping" },
        "links": { "$sum": "$link" }
    }},
    { "$group": {
       "_id": {
           "customerId": "$_id.customerId",
           "day": "$_id.day"
       },
       "hours": { 
           "$push": { 
               "hour": "$_id.hour",
               "pings": "$pings",
               "links": "$links"
           }
       }
    }}
])

Ngoài ra, tôi gần như quên đề cập rằng các giá trị của bạn cho "ping" và "liên kết" thực sự là các chuỗi trừ khi đó là lỗi đánh máy. Nhưng nếu không, trước tiên hãy đảm bảo rằng bạn chuyển đổi chúng dưới dạng số.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Tại sao tôi nhận được cảnh báo không dùng nữa này ?! MongoDB

  2. Truy vấn tổng hợp MongoDb với $ group và $ push vào subocument

  3. Duy trì tên thuộc tính Id trong tài liệu nhúng với trình điều khiển C # mongo

  4. Đường dẫn tổng hợp MongoDB chậm sau bước đối sánh đầu tiên

  5. MongoDB:Khóa duy nhất trong tài liệu nhúng