MongoDB
 sql >> база данни >  >> NoSQL >> MongoDB

Намерете последния запис за всеки ден

Малко по-модерен от оригиналния отговор:

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

Прилага се същият принцип, че по същество $sort колекцията и след това $group върху необходимия ключ за групиране, като вземете $last данни от границата на групиране.

Правейки нещата малко по-ясни след оригиналното писане е, че можете да използвате $$ROOT вместо да посочвате всяко свойство на документа и, разбира се, $replaceRoot етап ви позволява да възстановите тези данни напълно като оригиналната форма на документ.

Но общото решение все още е $sort първо, след това $group върху общия ключ, който се изисква, и запазете $last или $first в зависимост от възникването на реда на сортиране от границата на групиране за необходимите свойства.

Също така за BSON дати, за разлика от стойността на клеймото за време, както е във въпроса, вижте Групиран резултат по 15 минути интервал от време в MongoDb за различни подходи за това как да се натрупват за различни интервали от време, като действително се използват и връщат BSON стойности за дата.

Не съм съвсем сигурен какво търсите тук, но бихте могли да направите това обобщено, ако разбирам правилно. И така, за да получите последния запис за всеки ден:

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" },
    }}
])

Така че принципът тук е, че като се има предвид стойността на клеймото за време, направете математиката на датата, за да проектирате това като полунощ в началото на всеки ден. След това като _id ключ на документа вече е монотонен (винаги се увеличава), тогава просто групирайте на wholeDay стойност, докато изтегляте $last документ от границата на групиране.

Ако нямате нужда от всички полета, тогава проектирайте и групирайте само тези, които искате.

И да, можете да направите това в пролетната рамка на данни. Сигурен съм, че там има опакована команда. Но в противен случай заклинанието за достигане до основната команда е нещо подобно:

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

За протокола, ако действително сте имали BSON типове дати, а не клеймо за време като число, можете да пропуснете изчислението на датата:

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. Как да сортирате и ограничите резултатите в mongodb?

  2. Изчакване на NodeJS + Mongoose при връзка

  3. Използване на $push в рамките на Array в mongoose

  4. Какъв е правилният модел за вложени схеми в Mongoose/MongoDB?

  5. разбират MongoDB кеш система