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

Kết quả nhóm theo khoảng thời gian 15 phút trong MongoDb

Có một số cách để làm điều này.

Đầu tiên là với Toán tử Tổng hợp Ngày tháng, cho phép bạn phân tích các giá trị "ngày tháng" trong tài liệu. Cụ thể cho "nhóm" làm mục đích chính:

db.collection.aggregate([
  { "$group": {
    "_id": {
      "year": { "$year": "$created_at" },
      "dayOfYear": { "$dayOfYear": "$created_at" },
      "hour": { "$hour": "$created_at" },
      "interval": {
        "$subtract": [ 
          { "$minute": "$created_at" },
          { "$mod": [{ "$minute": "$created_at"}, 15] }
        ]
      }
    }},
    "count": { "$sum": 1 }
  }}
])

Cách thứ hai là sử dụng một mẹo nhỏ về thời điểm một đối tượng ngày bị trừ (hoặc phép toán trực tiếp khác) khỏi đối tượng ngày khác, khi đó kết quả là một giá trị số đại diện cho dấu thời gian kỷ nguyên mili giây giữa hai đối tượng. Vì vậy, chỉ cần sử dụng ngày kỷ nguyên, bạn sẽ có được đại diện cho phần nghìn giây của kỷ nguyên. Sau đó, sử dụng toán học ngày cho khoảng thời gian:

db.collection.aggregate([
    { "$group": {
        "_id": {
            "$subtract": [
                { "$subtract": [ "$created_at", new Date("1970-01-01") ] },
                { "$mod": [ 
                    { "$subtract": [ "$created_at", new Date("1970-01-01") ] },
                    1000 * 60 * 15
                ]}
            ]
        },
        "count": { "$sum": 1 }
    }}
])

Vì vậy, nó phụ thuộc vào loại định dạng đầu ra bạn muốn cho khoảng thời gian nhóm. Về cơ bản, cả hai đều đại diện cho cùng một thứ và có đủ dữ liệu để xây dựng lại dưới dạng đối tượng "ngày tháng" trong mã của bạn.

Bạn có thể đặt bất kỳ thứ gì khác mà bạn muốn vào phần "toán tử nhóm" sau _id nhóm . Tôi chỉ đang sử dụng ví dụ "đếm" cơ bản thay cho bất kỳ tuyên bố thực tế nào của bạn về những gì bạn thực sự muốn làm.

MongoDB 4.x trở lên

Đã có một số bổ sung cho Toán tử tổng hợp ngày kể từ bản viết gốc, nhưng từ MongoDB 4.0 sẽ có "thực tế đúc các kiểu" trái ngược với các thủ thuật toán học cơ bản được thực hiện ở đây với chuyển đổi Ngày của BSON.

Ví dụ:chúng ta có thể sử dụng $toLong$toDate với tư cách là những người trợ giúp mới tại đây:

db.collection.aggregate([
  { "$group": {
    "_id": {
      "$toDate": {
        "$subtract": [
          { "$toLong": "$created_at" },
          { "$mod": [ { "$toLong": "$created_at" }, 1000 * 60 * 15 ] }
        ]
      }
    },
    "count": { "$sum": 1 }
  }}
])

Điều đó ngắn hơn một chút và không yêu cầu xác định Ngày BSON bên ngoài cho giá trị "epoch" như một hằng số trong việc xác định đường dẫn, vì vậy nó khá nhất quán cho tất cả các triển khai ngôn ngữ.

Đó chỉ là hai trong số các phương thức "trợ giúp" để chuyển đổi kiểu, tất cả đều liên quan đến $convert , là một dạng triển khai "dài hơn" cho phép xử lý tùy chỉnh trên null hoặc lỗi trong chuyển đổi.

Thậm chí có thể với việc truyền như vậy để có được Date thông tin từ ObjectId của khóa chính, vì đây sẽ là nguồn đáng tin cậy về ngày "tạo":

db.collection.aggregate([
  { "$group": {
    "_id": {
      "$toDate": {
        "$subtract": [
          { "$toLong": { "$toDate": "$_id" }  },
          { "$mod": [ { "$toLong": { "$toDate": "$_id" } }, 1000 * 60 * 15 ] }
        ]
      }
    },
    "count": { "$sum": 1 }
  }}
])

Vì vậy, "kiểu truyền" với kiểu chuyển đổi này có thể là một công cụ khá mạnh mẽ.

Cảnh báo - ObjectId giá trị được giới hạn ở độ chính xác đến giây chỉ cho giá trị thời gian nội bộ tạo nên một phần dữ liệu của chúng cho phép $toDate sự chuyển đổi. "Thời gian" được chèn thực tế có lẽ phụ thuộc nhiều nhất vào trình điều khiển được sử dụng. Ở đâu độ chính xác là bắt buộc, bạn vẫn nên sử dụng trường Ngày BSON rời rạc thay vì dựa vào ObjectId giá trị.



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. MongoDB Seattle 2014

  2. Mongodb tìm bên trong mảng phụ

  3. MongoDB $ setDifference

  4. MongoDB:nâng cấp tài liệu phụ

  5. Sự cố với MongoDB GridFS Lưu tệp với Node.JS