MongoDB
 sql >> Baza danych >  >> NoSQL >> MongoDB

Znajdź ostatni rekord każdego dnia

Nieco bardziej nowoczesny niż pierwotna odpowiedź:

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

Ta sama zasada dotyczy zasadniczo $sort kolekcja, a następnie $group na wymaganym kluczu grupowania pobierając $last dane z granicy grupowania.

Uczynienie rzeczy nieco jaśniejszymi, ponieważ oryginalne pismo jest takie, że możesz użyć $$ROOT zamiast określania każdej właściwości dokumentu i oczywiście $replaceRoot etap umożliwia pełne przywrócenie tych danych w postaci oryginalnego dokumentu.

Ale ogólne rozwiązanie to nadal $sort najpierw $group we wspólnym kluczu, który jest wymagany i zachowaj $last lub $first w zależności od kolejności sortowania wystąpień z granicy grupowania dla wymaganych właściwości.

Również w przypadku dat BSON, w przeciwieństwie do wartości znacznika czasu, jak w pytaniu, zobacz Grupuj wyniki według 15-minutowego przedziału czasu w MongoDb dla różnych podejść do tego, jak akumulować dla różnych przedziałów czasu, faktycznie używając i zwracając wartości daty BSON.

Nie jestem do końca pewien, do czego zmierzasz, ale możesz to zrobić łącznie, jeśli moje zrozumienie jest właściwe. Aby uzyskać ostatni rekord każdego dnia:

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

Więc zasada jest taka, że ​​biorąc pod uwagę wartość znacznika czasu, wykonaj matematykę z datą, aby wyświetlić ją jako godzinę północy na początku każdego dnia. Następnie jako _id klawisz na dokumencie jest już monotoniczny (zawsze rosnący), a następnie po prostu zgrupuj na cały dzień wartość podczas wyciągania $last dokument od granicy grupowania.

Jeśli nie potrzebujesz wszystkich pól, projektuj i grupuj tylko te, które chcesz.

I tak, możesz to zrobić w ramach Spring Data Framework. Jestem pewien, że jest tam opakowane polecenie. Ale w przeciwnym razie zaklęcie, aby dostać się do natywnego polecenia, wygląda mniej więcej tak:

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

Dla przypomnienia, jeśli faktycznie masz typy dat BSON, a nie znacznik czasu jako liczbę, możesz pominąć matematykę daty:

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. Jak wykonywać podstawowe operacje na zapytaniach w MongoDB

  2. Zwróć tylko wartość tablicy w projekcji mongo

  3. MongoDb Post formatowanie agregacji $lookup z ograniczoną ilością danych

  4. Jak używać agregacji w mongodb do $match _id

  5. Jak zwrócić tablicę ciągów za pomocą agregacji mongodb?