it-swarm.asia

Perbedaan antara panggilan find dan findo MongoDB

Saya sedang mengerjakan suatu proyek dan saya tidak yakin apakah ada perbedaan antara cara kursor find bekerja dan cara kursor findOne bekerja. Apakah findOne hanya pembungkus untuk find().limit(1)? Saya mencari-cari dan mungkin seseorang tahu apakah mongodb memiliki metode khusus untuk itu atau tidak. Saya bekerja dengan API PHP untuk mongodb jika itu membuat perbedaan.

35
WojonsTech

Berdasarkan tolok ukur saya sendiri, find().limit(1) adalah urutan besarnya lebih cepat daripada findOne().

Ada kesalahan dalam dokumentasi MongoDB atau bug di findOne(). findOne() melakukan lebih seperti find().limit(N) di mana N adalah jumlah dokumen yang akan dikembalikan oleh query. Saya menemukan ini saat mencoba mencari tahu mengapa pertanyaan sederhana saya sangat lambat!

perbarui: respons dari insinyur 10gen (MongoDB):

Dua pertanyaan yang Anda jalankan sangat berbeda. Query find mengembalikan kursor, ini pada dasarnya adalah skenario tanpa operasi, karena tidak ada data aktual yang dikembalikan (hanya informasi kursor). Jika Anda memanggil findOne, maka Anda sebenarnya mengembalikan data dan menutup kursor. Dokumen pasti harus lebih jelas :-)

Pembaruan: Memang, jika dokumen find().limit(1) diambil, urutan perbedaan kecepatan magnitudo tampaknya menghilang. Juga, saya tidak dapat mereproduksi perbedaan kecepatan utama dengan driver JavaScript MongoDB. Saya awalnya diperbandingkan menggunakan MongoDB Java driver.

34
Leftium

findOne() memang gula sintaksis untuk find().limit(1), mengingat Anda benar-benar mengambil dokumen (bukan hanya mengembalikan kursor dengan find()).

Lihat jawaban Leftium dan pembaruan untuk detail lebih lanjut.

6
Nick Chammas

Kode sumber mungkin banyak membantu.

Ini Java tapi saya kira itu bisa membantu juga.

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

Dan ini adalah find()

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

Seperti yang dapat kita lihat bahwa findOne() memanggil find() di dalamnya sendiri, dapatkan semua DBOject di i dan kemudian kembalikan yang pertama.

3
shellbye