it-swarm.dev

Różnica między znajdowaniem i znajdowaniem wywołań MongoDB

Pracuję nad projektem i nie jestem pewien, czy istnieje różnica między sposobem działania kursora find a sposobem działania kursora findOne. Czy findOne jest tylko opakowaniem dla find().limit(1)? Rozglądałem się i może ktoś wie, czy mongodb ma do tego specjalną metodę, czy nie. Pracuję z interfejsem PHP API dla mongodb, jeśli to robi różnicę).

35
WojonsTech

Na podstawie moich własnych testów, find().limit(1) jest rzędami wielkości szybciej niż findOne().

Wystąpił błąd w dokumentacji MongoDB lub błąd w findOne(). findOne() działa bardziej jak find().limit(N) gdzie N jest liczbą dokumentów, które zwróci zapytanie. Zrozumiałem to, próbując dowiedzieć się, dlaczego moje proste zapytania były tak wolne!

aktualizacja: odpowiedź inżyniera 10gen (MongoDB):

Dwa wykonywane zapytania są bardzo różne. Zapytanie wyszukujące zwraca kursor, jest to zasadniczo scenariusz braku operacji, ponieważ żadne rzeczywiste dane nie są zwracane (tylko informacje o kursorze). Jeśli wywołasz findOne, w rzeczywistości zwracasz dane i zamykasz kursor. Dokumenty powinny zdecydowanie być jaśniejsze :-)

Aktualizacja: Rzeczywiście, jeśli dokument find().limit(1) zostanie pobrany, wydaje się, że rzędy różnicy prędkości prędkości znikają. Ponadto nie mogłem odtworzyć głównej różnicy prędkości ze sterownikiem JavaScript MongoDB. Pierwotnie testowałem przy użyciu MongoDB Java.

34
Leftium

findOne() jest rzeczywiście cukier składniowy dla find().limit(1), , biorąc pod uwagę, że faktycznie pobierasz dokument (w przeciwieństwie do zwykłego zwracania kursora za pomocą find()).

Zobacz odpowiedź Leftium i aktualizacje, aby uzyskać więcej szczegółów.

6
Nick Chammas

Kod źródłowy może bardzo pomóc.

To jest Java, ale myślę, że to też może pomóc.

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;
}

A oto find()

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

Jak widzimy, że findOne() wywołuje find() w sobie, pobiera wszystkie DBOject w i, a następnie zwraca pierwszą.

3
shellbye