عنوان:

‫استفاده از Luke برای بهبود کیفیت جستجوی لوسین


نویسنده: وحید نصیری
تاریخ: ۱۳۹۱/۰۴/۲۵ ۲۳:۱۷
آدرس: www.dntips.ir
به صورت خلاصه اگر نیاز به جستجوی سریع و پیشرفته‌ای بر روی حجم عظیمی از اطلاعات دارید، روش متداول select * from table where field like something توصیه نمی‌شود. بسیار کند است؛ مصرف CPU بالایی دارد. از ایندکس استفاده نمی‌کند.
راه حل توصیه شده جهت برخورد با این نوع مسایل استفاده از full text search است. نگارش کامل SQL Server حاوی یک موتور FTS توکار هست . اگر از بانک اطلاعاتی خاصی استفاده می‌کنید که دارای موتور FTS نیست یا ... FTS مخصوص SQL Server به درد کار شما نمی‌خورد یا نیاز به سفارشی سازی دارد (مثلا امکان تعریف stop words فارسی (کلماتی مانند به، از، تا و امثال آن))، از موتور FTS جانبی دیگری به نام لوسین نیز می‌توان استفاده کرد.

در کنار این‌ها ابزاری برای آنالیز و کوئری گرفتن از فایل‌های ایندکس تهیه شده توسط لوسین نیز وجود دارد به نام Luke. برای نمونه اگر بانک اطلاعاتی سایت جاری را با لوسین به نحو متداولی ایندکس کنیم، در صفحه اول این برنامه، top ranking terms آن به شکل زیر ظاهر می‌شود:


در اینجا چون متون تهیه شده از نوع HTML هستند، تگ br در آن‌ها زیاد است و یا یک سری حروف و کلمات فارسی هم در صدر قرار دارند که بهتر است از لیست ایندکس حذف شوند. برای اینکار تنها کافی است یک hash table را به نحو زیر تعریف و به StandardAnalyzer لوسین ارسال کنیم:
var stopWords = new Hashtable();
stopWords.Add("br","br");
// ...
var analyzer = new StandardAnalyzer(Version.LUCENE_29, stopWords);

یا آقای عرب عامری برای حروف و کلمات فارسی که نباید ایندکس شوند، یک لیست نسبتا جامع را در اینجا تهیه کرده‌اند.
اینبار اگر stop words یاد شده را اعمال و مجددا ایندکس‌ها را تهیه کنیم به خروجی بهتری خواهیم رسید.
در کل حداقل از این لحاظ، لوسین نسبت به FTS توکار SQL Server مناسب‌تر به نظر می‌رسد.

 

نظرات

  • شهروز جعفری در ۱۳۹۱/۰۴/۲۶ ۰:۸
    سلام
    یه سری از این نمونه‌ها از کد  زیر استفاده شده
     //////////// Begin the new section
        QueryParser oParser = new QueryParser("Body", new StandardAnalyzer());
        string sTitle = "", sWriterID = "", finalQuery = "";
     
        sTitle = " AND (Title:" + titleTerm + ")";
     
        sWriterID = " AND (WriterID:" + writerID + ")";
     
        finalQuery = "(" + bodyTerm + sTitle + sWriterID + ")";
        hits = searcher.Search(oParser.Parse(finalQuery));
        //////////// End of the new section
    که به نظرم حرفه ای نیست.
    در ضمن اگه میشه چند تا سایت برای استفاده از کتابخانه در Entity framework معرفی کنید.
    • وحید نصیری در ۱۳۹۱/۰۴/۲۶ ۰:۴۷
      کاری به EF نداره. به شکل یک سیستم مستقل بهش نگاه کنید. رکوردها از Db دریافت و به شکل document به لوسین اضافه خواهند شد. در همین حین index هم تشکیل می‌شود.
      کوئری‌های آن دقیقا به همین شکلی هست که در بالا اومده و زبان آن SQL نیست.
      البته پروژه LINQ به آن هم وجود دارد: (^)

  • رضا بزرگی در ۱۳۹۱/۰۴/۲۷ ۱۱:۵۴
    برای full text search در زبان فارسی این 150 کلمه که آقا عرب‌عامری زحمت کشیدن اصلا کفایت نمیکند. زبان فارسی و دیکته‌اش به این نحو اصلا مناسب ایندکس کردن نیست و بیشتر نیاز به توسعه دارد.
    شاید اگر بشه با ابزارهای توسعه‌ای که روی زبان فارسی کار شده - مثل ویراسباز ^ - خروجی بگیریم برای ایندکس کردن و در نتیجه تحلیل اونا به وسیله همین کتابخونه Luke یا  Solr یا Nutch - که در وبلاگ آقای زبردست معرفی شده ^  - آسونتره.
    • وحید نصیری در ۱۳۹۱/۰۴/۲۷ ۱۳:۵
      کار آقای عرب عامری فراتر است از 150 کلمه ذکر شده. آنالیز فتحه، کسره، ی فارسی و عربی و غیره هم در آن لحاظ شده.
      • رضا بزرگی در ۱۳۹۱/۰۴/۲۸ ۰:۰
        جستجو که در سایت همکنون هست، از همین کتابخانه استفاده میکنه یا توسعه داده شده؟
        یه سوال شاید بی‌ربط. در آنالیز نتایج شاخص‌های لوسین ضریبی غیر از تعداد دفعات تکرار شاخص مد نظر هست؟
        • وحید نصیری در ۱۳۹۱/۰۴/۲۸ ۰:۲۶
          - از کتابخانه اصلی lucene.net استفاده شده.
          - توضیحات مفصلش رو می‌تونید اینجا مطالعه کنید.
          • مهدی پایروند در ۱۳۹۱/۰۷/۱۰ ۱۳:۳۶
            مهندس پیشنیاز اجرای Luke در ویندوز 7 چی؟
             این آدرس لینک کلی کامپوننت برای دانلود گذاشته
            • وحید نصیری در ۱۳۹۱/۰۷/۱۰ ۱۳:۳۹
              - فایل‌های jar نیاز به موتور اجرایی جاوا (JRE) دارند.
              - luke نسخه دات نتی هم دارد.
          • مهدی پایروند در ۱۳۹۱/۰۷/۱۲ ۱۵:۲۹
            ممنون برای من خیلی مورد استفاده بوده
  • مهدی پایروند در ۱۳۹۱/۰۷/۱۲ ۱۵:۲۵
    واقعا کتابخانه سریعی هستش برای کاری که من داشتم نزدیک به 16 هزار رکود 10 فیلدی رو توی لوسین ایندکس کرد که برای دریافت نتایجش زمان خیلی کمتری رو گرفت.
    • وحید نصیری در ۱۳۹۱/۰۷/۱۲ ۱۷:۲۶
      بله. اینقدر باکیفیت است که RavenDB برای سیستم جستجوی خودش از لوسین به صورت توکار استفاده می‌کنه.
  • مهدی پایروند در ۱۳۹۱/۰۷/۱۲ ۱۵:۳۷
    در مورد این تصویر کمی توضیح میدین که به کدوم بخش لوسین مربوطه ممنون


    • وحید نصیری در ۱۳۹۱/۰۷/۱۲ ۱۷:۱۱
      این عدد درصد نزدیک بودن جواب به جستجوی انجام شده است (رتبه جستجوی لوسین). فرمول محاسبه آن به صورت زیر است:
      var hits = searcher.Search(query, 10).ScoreDocs;
      var scoreNorm = 100.0f / hits.GetMaxScore();
      foreach (var scoreDoc in hits)
      {
         var resultScore = scoreNorm * scoreDoc.score;
      }

  • مهدی پایروند در ۱۳۹۱/۰۷/۱۳ ۲۳:۵
    آیا برای صفحه بندی معادلی برای skip و  take وجود داره، با توجه به جستجویی که من انجام دادم ( + و + و + و + و + و + و + و + ) نمونه‌ای دال بر وجود یک همچین امکانی ندیدم.
    • وحید نصیری در ۱۳۹۱/۰۷/۱۳ ۲۳:۳۵
      - سؤال شما مرتبط با بحث Luke نیست.
      - و ... نداره. هر بار باید جستجو کنید. بعد روی نتیجه حاصل صفحه بندی رو انجام بدید. یا می‌تونید نتیجه جستجوی خاص انجام شده رو کش کنید تا سربار جستجوی مجدد حذف شود. (هرچند اینقدر سریع است که نیازی به کش نیست)
      • مهدی پایروند در ۱۳۹۱/۰۷/۱۴ ۱۹:۴۴
        بابت پاسختون ممنونم
  • وحید نصیری در ۱۳۹۶/۰۳/۰۷ ۱۵:۶
    جهت اطلاع
    کتابخانه‌ی « DNTPersianUtils.Core » به همراه PersianStopwords.List کاملتری است.
  • ابوالفضل بهاری س در ۱۳۹۷/۰۸/۰۵ ۱۶:۲۹
    چرا پوشه Lucene رو انتخاب میکنیم خطا رخ میده؟

    از اخرین نسخه لوسین استفاده میکنم؟

    • وحید نصیری در ۱۳۹۷/۰۸/۰۵ ۱۹:۵۱
      داخل پوشه‌ی لوسین شما چنین فایل‌هایی موجود هستند؟

      • ابوالفضل بهاری س در ۱۳۹۷/۰۸/۰۶ ۱۰:۷
        این فایل‌ها داخل فولدر هست
        ممنون میشم راهنمایی کنید سپاس

        • وحید نصیری در ۱۳۹۷/۰۸/۰۶ ۱۰:۲۷
          با استفاده از lukeall-3.5.0.jar ، مشکلی مشاهده نشد (لوسین دات نت، با نگارش 3x لوسین اصلی تطابق دارد):