it-swarm.it

Differenza tra le chiamate find e findone di MongoDB

Sto lavorando a un progetto e non sono sicuro che ci sia una differenza tra il modo in cui funziona il cursore find e il modo in cui funziona il cursore findOne. FindOne è solo un wrapper per find().limit(1)? Lo stavo cercando e forse qualcuno sa se mongodb ha un metodo speciale o no. Sto lavorando con l'API PHP per mongodb se questo fa la differenza.

35
WojonsTech

Basato sui miei parametri di riferimento, find().limit(1) è ordini di grandezza più veloci di findOne().

C'è un errore nella documentazione di MongoDB o un errore in findOne(). findOne() esegue di più come find().limit(N) dove N è il numero di documenti che la query restituirebbe. L'ho capito mentre cercavo di capire perché le mie semplici domande fossero così lente!

aggiornamento: risposta di un ingegnere 10gen (MongoDB):

Le due query che stai eseguendo sono molto diverse. Una query di ricerca restituisce un cursore, si tratta essenzialmente di uno scenario senza operazioni, poiché non vengono restituiti dati effettivi (solo le informazioni del cursore). Se chiami findOne, stai effettivamente restituendo i dati e chiudendo il cursore. I documenti dovrebbero essere sicuramente più chiari :-)

Aggiornamento: In effetti, se viene recuperato il documento find().limit(1), gli ordini di differenza di velocità della grandezza sembrano scomparire. Inoltre, non sono riuscito a riprodurre la maggiore differenza di velocità con il driver JavaScript MongoDB. Inizialmente ho fatto un benchmark usando MongoDB Java.

34
Leftium

findOne() è effettivamente zucchero sintattico per find().limit(1), dato che stai effettivamente recuperando il documento (anziché restituire semplicemente il cursore con find()).

Vedi La risposta di Leftium e aggiornamenti per maggiori dettagli.

6
Nick Chammas

Il codice sorgente può aiutare molto.

È Java ma immagino che possa aiutare anche.

Il findOne(),

DBObject findOne(DBObject o, DBObject fields, DBObject orderBy, ReadPreference readPref,
                 long maxTime, TimeUnit maxTimeUnit) {

    QueryOpBuilder queryOpBuilder = new QueryOpBuilder().addQuery(o).addOrderBy(orderBy)
                                                        .addMaxTimeMS(MILLISECONDS.convert(maxTime, maxTimeUnit));

    if (getDB().getMongo().isMongosConnection()) {
        queryOpBuilder.addReadPreference(readPref);
    }

    Iterator<DBObject> i = find(queryOpBuilder.get(), fields, 0, -1, 0, getOptions(), readPref, getDecoder());

    DBObject obj = (i.hasNext() ? i.next() : null);
    if ( obj != null && ( fields != null && fields.keySet().size() > 0 ) ){
        obj.markAsPartialObject();
    }
    return obj;
}

Ed ecco find()

public DBCursor find( DBObject ref ){
    return new DBCursor( this, ref, null, getReadPreference());
}

Come possiamo vedere che findOne() chiama find() in se stesso, ottiene tutto il DBOject in i e quindi restituisce il primo.

3
shellbye