منع "عدد كبير جدًا من البنود" في استعلام لوسين

StackOverflow https://stackoverflow.com/questions/614758

  •  03-07-2019
  •  | 
  •  

سؤال

في اختباراتي، صادفت فجأة استثناء "عدد كبير جدًا من البنود" عند محاولتي الحصول على النتائج من استعلام منطقي يتكون من استعلام مصطلحي واستعلام بدل.

لقد بحثت في جميع أنحاء الشبكة وعلى الموارد التي تم العثور عليها يقترحون زيادة BooleanQuery.SetMaxClauseCount().
هذا يبدو مريباً بالنسبة لي..إلى ماذا يجب أن يصل ذلك؟كيف يمكنني الاعتماد على أن هذا الرقم السحري الجديد سيكون كافيًا لاستعلامي؟إلى أي مدى يمكنني زيادة هذا الرقم قبل أن ينهار كل شيء؟

بشكل عام أشعر أن هذا ليس حلاً.لا بد أن هناك مشكلة أعمق..

كان الاستعلام +{+companyName:mercedes +paintCode:a*} ويحتوي الفهرس على 2.5 مليون مستند تقريبًا.

هل كانت مفيدة؟

المحلول

وعلى paintCode: أ * جزء من الاستعلام استعلام البادئة لأي paintCode بدءا من "أ". هل هذا ما كنت تهدف ل؟

لوسين يوسع الاستفسارات بادئة إلى استعلام منطقية تحتوي على جميع العبارات الممكنة التي تطابق البادئة. في حالتك، يبدو أن هناك أكثر من 1024 paintCodes الممكن أن تبدأ "أ".

وإذا كان يبدو لك مثل الاستفسارات بادئة عديمة الفائدة، وكنت لا يبعد كثيرا عن الحقيقة.

وأود أن أقترح عليك تغيير نظام الفهرسة تجنب استخدام استعلام البادئة. لست متأكدا ما كنت تحاول تحقيق مع المثال الخاص بك، ولكن إذا كنت تريد البحث عن رموز الطلاء من قبل الحرف الأول، وجعل حقل paintCodeFirstLetter والبحث من قبل هذا المجال.

مضاف

إذا كنت يائسة، ونحن مستعدون لقبول النتائج الجزئية، يمكنك بناء الإصدار الخاص بك لوسين بك من المصدر. تحتاج إلى إجراء تغييرات على PrefixQuery.java الملفات وMultiTermQuery.java، سواء في إطار org/apache/lucene/search. في طريقة rewrite كل الطبقات، وتغيير خط

query.add(tq, BooleanClause.Occur.SHOULD);          // add to query

إلى

try {
    query.add(tq, BooleanClause.Occur.SHOULD);          // add to query
} catch (TooManyClauses e) {
    break;
}

وأنا فعلت هذا لمشروع بلدي ويعمل.

إذا كنت حقا لا أحب فكرة تغيير لوسين، يمكن أن تكتب بنفسك PrefixQuery البديل وQueryParser الخاصة بك، ولكن لا أعتقد أنه من الأفضل بكثير.

نصائح أخرى

يبدو أنك تستخدم هذا في حقل يشبه إلى حد ما الكلمة الرئيسية اكتب (بمعنى أنه لن يكون هناك رموز مميزة متعددة في حقل مصدر البيانات الخاص بك).

هناك اقتراح هنا يبدو أنيقًا جدًا بالنسبة لي: http://grokbase.com/t/lucene.apache.org/java-user/2007/11/substring-indexing-to-avoid-toomanyclauses-exception/12f7s7kzp2emktbn66tdmfpcxfya

الفكرة الأساسية هي تقسيم المصطلح الخاص بك إلى حقول متعددة مع زيادة الطول حتى تكون متأكدًا تمامًا من أنك لن تصل إلى الحد الأقصى للشرط.

مثال:

تخيل رمز الطلاء مثل هذا:

"a4c2d3"

عند فهرسة هذه القيمة، يمكنك إنشاء قيم الحقول التالية في مستندك:

[paintCode]: "a4c2d3"

[paintCode1n]: "a"

[paintCode2n]: "a4"

[paintCode3n]: "a4c"

بحلول الوقت الذي تقوم فيه بالاستعلام، فإن عدد الأحرف في مصطلحك هو الذي يحدد الحقل الذي سيتم البحث فيه.هذا يعني أنك ستقوم بإجراء استعلام عن البادئة فقط للمصطلحات التي تحتوي على أكثر من 3 أحرف، مما يقلل بشكل كبير من عدد النتائج الداخلية، ويمنع حدوث حالات سيئة السمعة TooManyBooleanClausesException.ويبدو أن هذا أيضًا يسرع عملية البحث.

يمكنك بسهولة أتمتة عملية تقسيم المصطلحات تلقائيًا وملء المستندات بالقيم وفقًا لنظام الأسماء أثناء الفهرسة.

قد تنشأ بعض المشكلات إذا كان لديك رموز مميزة متعددة لكل حقل.يمكنك العثور على مزيد من التفاصيل في المقال

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top