mongodb / mongoose findMany: trova tutti i documenti con ID elencati nella matrice


246

Ho una serie di _ids e voglio ottenere tutti i documenti di conseguenza, qual è il modo migliore per farlo?

Qualcosa di simile a ...

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

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

L'array potrebbe contenere centinaia di _ids.

Risposte:


479

La findfunzione in mongoose è una query completa per mongoDB. Ciò significa che è possibile utilizzare la pratica $inclausola mongoDB , che funziona esattamente come la versione SQL della stessa.

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

Questo metodo funzionerà bene anche per array contenenti decine di migliaia di ID. (Vedi Determinare in modo efficiente il proprietario di un record )

Consiglierei a chiunque lavori con di mongoDBleggere la sezione Advanced Queries dell'eccellente Documenti ufficiali di mongoDB


9
Un po 'tardi a questa discussione, ma come assicurereste che l'ordine degli articoli restituiti corrisponda all'ordine dell'array degli articoli forniti nell'array? Non è garantito che i documenti vengano pubblicati in alcun ordine se non si specifica un ordinamento. Che cosa succede se li desideri ordinati nello stesso ordine in cui li elenchi nell'array (ad es. ... 000c, ... 000d, ... 000e)?
Kevin,

7
Questo non ha funzionato per qualche motivo. Ho ricevuto una serie vuota di documenti
delizioso

2
@chovy prova prima a convertirli in ObjectIds , invece di passare stringhe.
Georgi Hristozov,

@GeorgiHristozov sto usando un generatore di ID personalizzato ... la conversione in ObjectId funziona ancora? (mongoose + shortid)
chovy

1
@Schybo che non fa assolutamente alcuna differenza. { _id : 5 }è lo stesso di { '_id' : 5 }.
Royowie il

28

Ids è l'array di id oggetto:

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

Utilizzo di Mongoose con callback:

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

Utilizzo di Mongoose con funzione asincrona:

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

Non dimenticare di cambiare modello con il tuo modello attuale.


Questa dovrebbe essere la risposta accettata in quanto è la più aggiornata e coerente. Non è necessario convertire gli ID in ObjectId come nella risposta accettata e utilizza le query di stile imperativo mongoose . Grazie a proposito!
Javi Marzán,

Questo è un metodo molto pulito e aggiornato, se non ti dispiace vorrei fare qualche domanda, se ho una serie di riferimenti ObjectIdcome sopra (diciamo, ho progetti e ho assegnato una matrice di progetti a determinati utenti con project_id a cui fa riferimento il modello utente), se elimino un progetto, come posso assicurarmi che idsia eliminato dall'array a cui fa riferimento il modello utente? Grazie mat.
Eazy

9

Utilizzare questo formato di query

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();

4

Sia node.js che MongoChef mi costringono a convertire in ObjectId. Questo è quello che uso per prendere un elenco di utenti dal DB e recuperare alcune proprietà. Fai attenzione alla conversione del tipo nella riga 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 );
                }
            }
        });
    }

7
userIds = _.map (elenco, funzione (userId) {return mongoose.Types.ObjectId (userId)};
Michael Draper,

1
Non ho dovuto convertire in ObjectID usando mongoose 4.5.9.
Florian Wendelborn,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.