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

Sortowanie według maksymalnego pola tablicy, rosnąco lub malejąco

Podstawowy problem z tym, o co tu pytasz, sprowadza się do faktu, że dane dane znajdują się w „tablicy”, a zatem MongoDB przyjmuje pewne podstawowe założenia dotyczące sposobu obsługi tego.

Jeśli zastosowałeś sortowanie w „kolejności malejącej”, MongoDB zrobi dokładnie to, o co poprosisz i posortuje dokumenty według „największej” wartości określonego pola w tablicy:

.sort({ "revisions.created": -1 ))

Ale jeśli zamiast tego sortujesz w kolejności „rosnąco”, to oczywiście jest odwrotnie i brana jest pod uwagę „najmniejsza” wartość.

.sort({ "revisions.created": 1 })

Jedynym sposobem na zrobienie tego jest ustalenie, która data jest maksymalna na podstawie danych w tablicy, a następnie sortowanie według tego wyniku. Zasadniczo oznacza to zastosowanie .aggregate() , co w przypadku Meteor jest operacją po stronie serwera, czyli niestety mniej więcej tak:

Collection.aggregate([
    { "$unwind": "$revisions" },
    { "$group": {
        "_id": "$_id",
        "name": { "$first": "$name" },
        "revisions": { "$push": "$revisions" },
        "number": { "$first": "$number" }
        "maxDate": { "$max": "$revisions.created" }
    }},
    { "$sort": { "maxDate": 1 }
])

Lub w najlepszym przypadku z MongoDB 3.2, gdzie $max można zastosować bezpośrednio do wyrażenia tablicowego:

Collection.aggregate([
    { "$project": {
        "name": 1,
        "revisions": 1,
        "number": 1,
        "maxDate": {
            "$max": {
                "$map": {
                    "input": "$revisions",
                    "as": "el",
                    "in": "$$el.created"
                }
            }
        }
    }},
    { "$sort": { "maxDate": 1 } }
])

Ale tak naprawdę oba nie są tak świetne, nawet jeśli podejście MongoDB 3.2 ma znacznie mniejsze obciążenie niż to, co jest dostępne we wcześniejszych wersjach, nadal nie jest tak dobre, jak można uzyskać pod względem wydajności ze względu na konieczność przesyłania danych i pracy podaj wartość do sortowania.

Więc dla najlepszego wydajność, „zawsze” przechowuj dane, których będziesz potrzebować, „poza” tablicą. Do tego jest $max Operator „aktualizacji”, który zastąpi wartość w dokumencie „jeśli” podana wartość jest „większa niż” istniejąca już tam wartość. tj.:

Collection.update(
    { "_id": "qTF8kEphNoB3eTNRA" },
    { 
        "$push": {
            "revisions": { "created": new Date("2016-02-01") }            
        },
        "$max": { "maxDate": new Date("2016-02-01") }
    }
)

Oznacza to, że żądana wartość „zawsze” będzie już obecna w dokumencie z oczekiwaną wartością, więc wystarczy teraz posortować według tego pola:

.sort({ "maxDate": 1 })

Więc za moje pieniądze, przejrzałbym istniejące dane za pomocą jednego z .aggregate() dostępne wyciągi i użyj tych wyników, aby zaktualizować każdy dokument tak, aby zawierał pole „maxDate”. Następnie zmień kodowanie wszystkich dodatków i poprawek danych tablicy, aby zastosować ten $max "aktualizuj" przy każdej zmianie.

Posiadanie solidnego pola zamiast obliczeń zawsze ma o wiele więcej sensu, jeśli używasz go wystarczająco często. A konserwacja jest dość prosta.

W każdym razie, biorąc pod uwagę powyższą przykładową datę, która jest "mniejsza niż" inne obecne maksymalne daty zwróciłyby się dla mnie we wszystkich formach:

{
        "_id" : "5xF9iDTj3reLDKNHh",
        "name" : "Lorem ipsum",
        "revisions" : [
                {
                        "number" : 0,
                        "comment" : "Dolor sit amet",
                        "created" : ISODate("2016-02-11T01:22:45.588Z")
                }
        ],
        "number" : 1,
        "maxDate" : ISODate("2016-02-11T01:22:45.588Z")
}
{
        "_id" : "qTF8kEphNoB3eTNRA",
        "name" : "Consecitur quinam",
        "revisions" : [
                {
                        "comment" : "Hoste ad poderiquem",
                        "number" : 1,
                        "created" : ISODate("2016-02-11T23:25:46.033Z")
                },
                {
                        "number" : 0,
                        "comment" : "Fagor questibilus",
                        "created" : ISODate("2016-02-11T01:22:45.588Z")
                },
                {
                        "created" : ISODate("2016-02-01T00:00:00Z")
                }
        ],
        "number" : 2,
        "maxDate" : ISODate("2016-02-11T23:25:46.033Z")
}

Który poprawnie umieszcza pierwszy dokument na górze kolejności sortowania z uwzględnieniem „maxDate”.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Aktualizowanie tablicy zagnieżdżonej wewnątrz tablicy mongodb

  2. mongodb:wstaw, jeśli nie istnieje

  3. Jak poprawnie zwiększyć liczbę dat w mongoDB?

  4. Kiedy używać CouchDB przez MongoDB i na odwrót?

  5. jak iterować kursor mongo w pętli w pythonie