MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

Mongoose-Filialdokumentsortierung

Ich hätte dies in ein paar Dinge schreiben können, aber bei der Überlegung scheint "die Mungo-Objekte zurückzubekommen" die Hauptüberlegung zu sein.

Es gibt also verschiedene Dinge, die Sie tun "könnten". Aber da Sie Referenzen in ein Objekt "auffüllen" und dann die Reihenfolge der Objekte in einem Array ändern möchten, gibt es wirklich nur einen Weg, dies ein für alle Mal zu beheben.

Ordnen Sie die Daten beim Erstellen in der richtigen Reihenfolge

Wenn Sie möchten, dass Ihr "comments"-Array nach dem Datum sortiert ist, an dem sie "created_at" sind, kann dies sogar in mehrere Möglichkeiten unterteilt werden:

  1. Es "sollte" in der "Einfüge" -Reihenfolge hinzugefügt werden, also ist das "Neueste" das letzte, wie Sie bemerken, aber Sie können dies auch in neueren (in den letzten paar Jahren) Versionen von MongoDB mit $position als Modifikator für $push :

    Article.update(
        { "_id": articleId },
        { 
            "$push": { "comments": { "$each": [newComment], "$position": 0 } }
        },
        function(err,result) {
            // other work in here
        }
    );
    

    Dadurch wird das Array-Element dem bestehenden Array am „ersten“ (0) Index „vorangestellt“, sodass es immer vorne steht.

  2. Wenn Sie aus logischen Gründen oder nur dort, wo Sie "sicher sein wollen", keine "positionellen" Aktualisierungen verwenden, gibt es für eine noch "längere" Zeit den $sort Modifikator zu $push :

    Article.update(
        { "_id": articleId },
        { 
            "$push": { 
                "comments": { 
                    "$each": [newComment], 
                    "$sort": { "$created_at": -1 } 
                }
            }
        },
        function(err,result) {
            // other work in here
        }
    );
    

    Und das wird nach der Eigenschaft der Array-Elemente Dokumente "sortieren", die den angegebenen Wert für jede Änderung enthalten. Sie können sogar:

    Article.update(
        {  },
        { 
            "$push": { 
                "comments": { 
                    "$each": [], 
                    "$sort": { "$created_at": -1 } 
                }
            }
        },
        { "multi": true },
        function(err,result) {
            // other work in here
        }
    );
    

    Und das wird jedes "comments"-Array in Ihrer gesamten Sammlung nach dem angegebenen Feld in einem Treffer sortieren.

Andere Lösungen sind möglich, indem entweder .aggregate() verwendet wird um das Array zu sortieren und/oder in Mongoose-Objekte umzuwandeln, nachdem Sie diese Operation durchgeführt haben oder nachdem Sie Ihr eigenes .sort() durchgeführt haben auf dem einfachen Objekt.

Bei beiden handelt es sich wirklich um die Erstellung eines separaten Modellobjekts und "Schemas" mit den eingebetteten Elementen, einschließlich der "referenzierten" Informationen. Sie könnten also an diesen Zeilen arbeiten, aber es scheint unnötiger Overhead zu sein, wenn Sie die Daten von Anfang an einfach nach Ihren "am dringendsten benötigten" Mitteln sortieren könnten.

Die Alternative besteht darin sicherzustellen, dass Felder wie „virtuals“ immer mit .toObject() in ein Objektformat „serialisiert“ werden auf Abruf und einfach damit leben, dass alle Methoden jetzt weg sind und mit den Eigenschaften wie dargestellt arbeiten.

Der letzte ist ein "vernünftiger" Ansatz, aber wenn Sie normalerweise die Reihenfolge "created_at" verwenden, ist es viel sinnvoller, Ihre Daten bei jeder Operation auf diese Weise zu "speichern", damit sie beim "Abrufen" in der bleiben Bestellung, die Sie verwenden werden.