mongodb / mongoose findMany - Alle Dokumente mit im Array aufgelisteten IDs finden

246

Ich habe eine Reihe von _ids und möchte alle Dokumente entsprechend abrufen. Wie geht das am besten?

Etwas wie ...

// doesn't work ... of course ...

model.find({
    '_id' : [
        '4ed3ede8844f0f351100000c',
        '4ed3f117a844e0471100000d', 
        '4ed3f18132f50c491100000e'
    ]
}, function(err, docs){
    console.log(docs);
});

Das Array kann Hunderte von _ids enthalten.

Ezmilhouse
quelle

Antworten:

479

Die findFunktion in Mungo ist eine vollständige Abfrage an MongoDB. Dies bedeutet, dass Sie die praktische mongoDB- $inKlausel verwenden können, die genau wie die SQL-Version derselben funktioniert.

model.find({
    '_id': { $in: [
        mongoose.Types.ObjectId('4ed3ede8844f0f351100000c'),
        mongoose.Types.ObjectId('4ed3f117a844e0471100000d'), 
        mongoose.Types.ObjectId('4ed3f18132f50c491100000e')
    ]}
}, function(err, docs){
     console.log(docs);
});

Diese Methode funktioniert auch für Arrays mit Zehntausenden von IDs. (Siehe Effizientes Bestimmen des Besitzers eines Datensatzes. )

Ich würde jedem empfehlen, der mit mongoDBdem Abschnitt " Erweiterte Abfragen " der hervorragenden offiziellen mongoDB-Dokumente durchliest

Daniel Mendel
quelle
9
Etwas spät zu dieser Diskussion, aber wie würden Sie sicherstellen, dass die Reihenfolge der zurückgegebenen Elemente mit der Reihenfolge des Arrays von Elementen übereinstimmt, die Sie im Array bereitstellen? Es wird nicht garantiert, dass Dokumente in beliebiger Reihenfolge ausgegeben werden, es sei denn, Sie geben eine Sortierung an. Was ist, wenn Sie möchten, dass sie in derselben Reihenfolge sortiert werden, in der Sie sie im Array auflisten (z. B. ... 000c, ... 000d, ... 000e)?
Kevin
7
Dies hat aus irgendeinem Grund nicht funktioniert. Ich habe eine leere Reihe von Dokumenten
chovy
2
@chovy versucht zuerst , sie in ObjectIds zu konvertieren , anstatt Zeichenfolgen zu übergeben.
Georgi Hristozov
@GeorgiHristozov Ich verwende einen benutzerdefinierten ID-Generator. Funktioniert die Konvertierung in ObjectId noch? (Mungo + Shortid)
Chovy
1
@Schybo das macht absolut keinen Unterschied. { _id : 5 }ist das gleiche wie { '_id' : 5 }.
Royhowie
27

IDs ist das Array von Objekt-IDs:

const ids =  [
    '4ed3ede8844f0f351100000c',
    '4ed3f117a844e0471100000d', 
    '4ed3f18132f50c491100000e',
];

Verwenden von Mongoose mit Rückruf:

Model.find().where('_id').in(ids).exec((err, records) => {});

Verwenden von Mongoose mit asynchroner Funktion:

records = await Model.find().where('_id').in(ids).exec();

Vergessen Sie nicht, das Modell mit Ihrem tatsächlichen Modell zu ändern.

SnnSnn
quelle
Dies sollte die akzeptierte Antwort sein, da sie die aktuellste und kohärenteste ist. Sie müssen die IDs nicht wie in der akzeptierten Antwort in ObjectId konvertieren, und es werden die Abfragen im imperativen Mungo- Stil verwendet. Danke übrigens!
Javi Marzán
Dies ist eine sehr saubere und aktualisierte Methode. Wenn Sie nichts dagegen haben, möchte ich ein paar Fragen stellen, wenn ich eine Reihe von referenzierten Methoden ObjectIdwie die oben genannten habe (z. B. habe ich Projekte und habe eine Reihe von zugewiesen Projekte an bestimmte Benutzer mit der Projekt-ID, auf die im Benutzermodell verwiesen wird) Wenn ich ein Projekt lösche, wie stelle ich sicher, dass das idaus dem Array gelöscht wird, auf das im Benutzermodell verwiesen wird? Danke mat.
Eazy
9

Verwenden Sie dieses Abfrageformat

let arr = _categories.map(ele => new mongoose.Types.ObjectId(ele.id));

Item.find({ vendorId: mongoose.Types.ObjectId(_vendorId) , status:'Active'})
  .where('category')
  .in(arr)
  .exec();
Derese Getachew
quelle
4

Sowohl node.js als auch MongoChef zwingen mich, in ObjectId zu konvertieren. Dies ist, was ich benutze, um eine Liste von Benutzern aus der Datenbank zu holen und einige Eigenschaften abzurufen. Beachten Sie die Typkonvertierung in Zeile 8.

// this will complement the list with userName and userPhotoUrl based on userId field in each item
augmentUserInfo = function(list, callback){
        var userIds = [];
        var users = [];         // shortcut to find them faster afterwards
        for (l in list) {       // first build the search array
            var o = list[l];
            if (o.userId) {
                userIds.push( new mongoose.Types.ObjectId( o.userId ) );           // for the Mongo query
                users[o.userId] = o;                                // to find the user quickly afterwards
            }
        }
        db.collection("users").find( {_id: {$in: userIds}} ).each(function(err, user) {
            if (err) callback( err, list);
            else {
                if (user && user._id) {
                    users[user._id].userName = user.fName;
                    users[user._id].userPhotoUrl = user.userPhotoUrl;
                } else {                        // end of list
                    callback( null, list );
                }
            }
        });
    }
Nico
quelle
7
userIds = _.map (Liste, Funktion (userId) {return mongoose.Types.ObjectId (userId)};
Michael Draper
1
Ich musste nicht mit Mungo 4.5.9 in ObjectID konvertieren.
Florian Wendelborn