mongodb / mongoose findMany - znajdź wszystkie dokumenty o identyfikatorach wymienionych w tablicy

246

Mam szereg _ids i chcę uzyskać wszystkie dokumenty odpowiednio, jaki jest najlepszy sposób, aby to zrobić?

Coś jak ...

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

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

Tablica może zawierać setki _ids.

ezmilhouse
źródło

Odpowiedzi:

479

findFunkcja w mangusta jest pełne zapytanie do MongoDB. Oznacza to, że możesz użyć przydatnej $inklauzuli mongoDB , która działa tak samo jak wersja SQL tego samego.

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

Ta metoda będzie działać dobrze nawet dla tablic zawierających dziesiątki tysięcy identyfikatorów. (Zobacz Skuteczne ustalenie właściciela rekordu )

Polecam wszystkim, którzy pracują z, mongoDBprzeczytanie sekcji Zaawansowane zapytania doskonałych oficjalnych dokumentów mongoDB

Daniel Mendel
źródło
9
Trochę późno w tej dyskusji, ale jak byś upewnił się, że kolejność zwracanych przedmiotów odpowiada kolejności tablicy przedmiotów, którą podajesz w tablicy? Dokumenty nie są gwarantowane w dowolnej kolejności, chyba że określisz rodzaj. Co jeśli chcesz je posortować w tej samej kolejności, umieścisz je w tablicy (np. ... 000c, ... 000d, ... 000e)?
Kevin
7
Z jakiegoś powodu to nie działało. Mam pustą tablicę dokumentów
chovy
2
@chovy spróbuj najpierw przekonwertować je na ObjectIds , zamiast przekazywać ciągi.
Georgi Hristozov
@GeorgiHristozov Używam niestandardowego generatora identyfikatorów ... Czy konwersja do ObjectId nadal działa? (mongoose + shortid)
chovy
1
@Schybo, które nie ma absolutnie żadnej różnicy. { _id : 5 }jest taki sam jak { '_id' : 5 }.
royhowie
27

ID to tablica identyfikatorów obiektów:

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

Używanie Mongoose z oddzwanianiem:

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

Używanie Mongoose z funkcją asynchroniczną:

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

Nie zapomnij zmienić modelu na rzeczywisty.

SnnSnn
źródło
To powinna być zaakceptowana odpowiedź, ponieważ jest najbardziej aktualna i spójna. Nie musisz konwertować identyfikatorów na ObjectId, jak w zaakceptowanej odpowiedzi, i używa on zapytań o imperatywny styl mangusty . Dzięki btw!
Javi Marzán
Jest to bardzo czysta i zaktualizowana metoda, jeśli nie masz nic przeciwko, chciałbym zadać kilka pytań, jeśli mam tablicę odnośników ObjectIdpodobną do powyższej (powiedzmy, że mam projekty i przypisałem tablicę projekty dla niektórych użytkowników z identyfikatorem projektu przywoływanym w modelu użytkownika), jeśli usunę projekt, jak mogę się upewnić, że idzostał on usunięty z tablicy, do której odwołuje się model użytkownika? Dzięki matko.
Eazy
9

Użyj tego formatu zapytań

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
źródło
4

Zarówno node.js, jak i MongoChef zmuszają mnie do konwersji na ObjectId. Właśnie tego używam, aby pobrać listę użytkowników z bazy danych i pobrać kilka właściwości. Zwróć uwagę na konwersję typu w linii 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
źródło
7
userIds = _.map (lista, funkcja (userId) {return mongoose.Types.ObjectId (userId)};
Michael Draper
1
Nie musiałem konwertować na ObjectID za pomocą mongoose 4.5.9.
Florian Wendelborn,