it-swarm.asia

الفرق بين مكالمات FindoDB و findone

أنا أعمل على مشروع ، ولست متأكدًا من وجود فرق بين طريقة عمل المؤشر find وطريقة عمل المؤشر findOne. هل findOne مجرد غلاف لـ find().limit(1)؟ كنت أبحث في كل مكان عن ذلك ، وربما شخص يعرف ما إذا كان mongodb لديه طريقة خاصة لذلك أم لا. أنا أعمل مع PHP API لـ mongodb إذا كان ذلك يحدث فرقًا.

35
WojonsTech

بناءً على مقاييسي الخاصة ، find().limit(1) هي أوامر بحجم أسرع من findOne().

يوجد خطأ في وثائق MongoDB أو خطأ في findOne(). findOne() تؤدي وظائفها مثل find().limit(N) حيث N هو عدد المستندات التي سيُرجعها الاستعلام. لقد اكتشفت ذلك أثناء محاولتي معرفة سبب بطء استفساراتي البسيطة!

التحديث: استجابة من مهندس 10gen (MongoDB):

إن الاستعلامين اللذين تقوم بتنفيذهما مختلفان للغاية. يقوم استعلام البحث بإرجاع المؤشر ، وهذا في الأساس سيناريو عدم التشغيل ، حيث لا يتم إرجاع أي بيانات فعلية (فقط معلومات المؤشر). إذا اتصلت ب findOne ، فأنت في الواقع تقوم بإرجاع البيانات وإغلاق المؤشر. يجب أن تكون المستندات أوضح :-)

تحديث: في الواقع ، إذا تم استرداد المستند find().limit(1) ، يبدو أن اختلافات سرعة السرعة تختفي. أيضا ، لم أستطع إعادة إنتاج فرق السرعة الرئيسي مع برنامج تشغيل JavaScript MongoDB. لقد قمت في الأصل بقياس الأداء باستخدام MongoDB Java driver.

34
Leftium

findOne() هي بالفعل السكر النحوي لـ find().limit(1) ، بالنظر إلى أنك تقوم بالفعل باسترداد المستند (على عكس إعادة المؤشر مع find()).

انظر إجابة Leftium والتحديثات لمزيد من التفاصيل.

6
Nick Chammas

قد يساعد رمز المصدر كثيرًا.

إنها Java ولكن أعتقد أنه يمكن أن يساعد أيضًا.

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

وهنا find()

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

كما نرى أن findOne() المكالمات find() في حد ذاتها ، تحصل على كل DBOject في i ثم ترجع الأولى.

3
shellbye