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

Tìm bản ghi cuối cùng của mỗi ngày

Hiện đại hơn một chút so với câu trả lời ban đầu:

db.collection.aggregate([
  { "$sort": { "date": 1 } },
  { "$group": {
    "_id": {
      "$subtract": ["$date",{"$mod": ["$date",86400000]}]
    },
    "doc": { "$last": "$$ROOT" }
  }},
  { "$replaceRoot": { "newDocument": "$doc" } }
])

Nguyên tắc tương tự áp dụng về cơ bản bạn $ sort tập hợp và sau đó là $ group trên khóa nhóm bắt buộc, chọn mã $ last dữ liệu từ ranh giới nhóm.

Làm cho mọi thứ rõ ràng hơn một chút vì văn bản gốc là bạn có thể sử dụng $$ ROOT thay vì chỉ định mọi thuộc tính tài liệu và tất nhiên là $ ReplaceRoot giai đoạn cho phép bạn khôi phục dữ liệu đó đầy đủ như ở dạng tài liệu ban đầu.

Nhưng giải pháp chung vẫn là $ sort trước tiên, sau đó đến $ group trên khóa chung được yêu cầu và giữ $ last hoặc $ first tùy thuộc vào sự xuất hiện của thứ tự sắp xếp từ ranh giới nhóm cho các thuộc tính được yêu cầu.

Ngoài ra đối với Ngày BSON thay vì giá trị dấu thời gian như trong câu hỏi, hãy xem Kết quả nhóm theo khoảng thời gian 15 phút trong MongoDb cho các phương pháp tiếp cận khác nhau về cách tích lũy trong các khoảng thời gian khác nhau thực sự sử dụng và trả về các giá trị Ngày BSON.

Không hoàn toàn chắc chắn bạn sẽ làm gì ở đây nhưng bạn có thể làm điều này tổng thể nếu sự hiểu biết của tôi là đúng. Vì vậy, để có được bản ghi cuối cùng cho mỗi ngày:

db.collection.aggregate([
    // Sort in date order  as ascending
    {"$sort": { "date": 1 } },

    // Date math converts to whole day
    {"$project": {
        "adco": 1,
        "hchc": 1,
        "hchp": 1,
        "hhphc": 1,
        "ptec": 1,
        "iinst": 1,
        "papp": 1,
        "imax": 1,
        "optarif": 1,
        "isousc": 1,
        "motdetat": 1,
        "date": 1,
        "wholeDay": {"$subtract": ["$date",{"$mod": ["$date",86400000]}]} 
    }},

    // Group on wholeDay ( _id insertion is monotonic )
    {"$group": 
        "_id": "$wholeDay",
        "docId": {"$last": "$_id" },
        "adco": {"$last": "$adco" },
        "hchc": {"$last": "$hchc" },
        "hchp": {"$last": "$hchp" },
        "hhphc": {"$last": "$hhphc" },
        "ptec": {"$last": "$ptec" },
        "iinst": {"$last": "$iinst" },
        "papp": {"$last": "$papp" },
        "imax": {"$last": "$imax" },
        "optarif": {"$last": "$optarif",
        "isousc": {"$last": "$isouc" },
        "motdetat": {"$last": "$motdetat" },
        "date": {"$last": "$date" },
    }}
])

Vì vậy, nguyên tắc ở đây là với giá trị dấu thời gian, hãy thực hiện phép toán ngày để dự đoán đó là thời gian nửa đêm vào đầu mỗi ngày. Sau đó là _id khóa trên tài liệu đã là đơn âm (luôn tăng), sau đó chỉ cần nhóm trên wholeDay giá trị trong khi kéo $ last tài liệu từ ranh giới nhóm.

Nếu bạn không cần tất cả các trường thì chỉ chiếu và nhóm trên những trường bạn muốn.

Và có, bạn có thể làm điều này trong khung dữ liệu mùa xuân. Tôi chắc chắn rằng có một lệnh được bao bọc trong đó. Nhưng nếu không, câu thần chú truy cập lệnh gốc sẽ giống như sau:

mongoOps.getCollection("yourCollection").aggregate( ... )

Đối với bản ghi, nếu bạn thực sự có các loại ngày BSON thay vì dấu thời gian dưới dạng số, thì bạn có thể bỏ qua phép toán ngày:

db.collection.aggregate([
    { "$group": { 
        "_id": { 
            "year": { "$year": "$date" },
            "month": { "$month": "$date" },
            "day": { "$dayOfMonth": "$date" }
        },
        "hchp": { "$last": "$hchp" }
    }}
])


  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Cách tìm tài liệu có các mục nhập mảng giống hệt như trong truy vấn

  2. Meteor - collection.find () luôn trả về tất cả các trường

  3. nhập tệp CSV MongoDB với ISODate

  4. Làm cách nào để sử dụng một trường từ tổng hợp trong một đối sánh regex $ trong mongodb?

  5. Làm cách nào để nối các mảng từ nhiều tài liệu trong MongoDB?