استخدام Lucene للبحث عن عناوين البريد الإلكتروني

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

  •  09-06-2019
  •  | 
  •  

سؤال

أريد استخدام Lucene (على وجه الخصوص، Lucene.NET) للبحث عن مجالات عناوين البريد الإلكتروني.

على سبيل المثالأريد البحث عن "@gmail.com" للعثور على جميع رسائل البريد الإلكتروني المرسلة إلى عنوان Gmail.

يؤدي تشغيل استعلام Lucene لـ "*@gmail.com" إلى حدوث خطأ، ولا يمكن أن تكون العلامات النجمية في بداية الاستعلامات.لا يؤدي تشغيل استعلام عن "@gmail.com" إلى ظهور أي تطابقات، لأنه يتم النظر إلى "foo@gmail.com" ككلمة كاملة، ولا يمكنك البحث عن أجزاء من الكلمة فقط.

كيف يمكنني أن أفعل هذا؟

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

المحلول

لم يقدم أحد إجابة مرضية، لذلك بدأنا في البحث عن وثائق Lucene واكتشفنا أنه يمكننا إنجاز ذلك باستخدام محللات ورموز مميزة مخصصة.

الجواب هو هذا:أنشئ WhitespaceAndAtSymbolTokenizer وWhitespaceAndAtSymbolAnalyzer، ثم أعد إنشاء الفهرس الخاص بك باستخدام هذا المحلل.بمجرد القيام بذلك، سيؤدي البحث عن "@gmail.com" إلى عرض جميع عناوين Gmail، لأنه يُنظر إليها على أنها كلمة منفصلة بفضل Tokenizer الذي أنشأناه للتو.

إليك الكود المصدري، وهو في الواقع بسيط جدًا:

class WhitespaceAndAtSymbolTokenizer : CharTokenizer
{
    public WhitespaceAndAtSymbolTokenizer(TextReader input)
        : base(input)
    {
    }

    protected override bool IsTokenChar(char c)
    {
        // Make whitespace characters and the @ symbol be indicators of new words.
        return !(char.IsWhiteSpace(c) || c == '@');
    }
}


internal class WhitespaceAndAtSymbolAnalyzer : Analyzer
{
    public override TokenStream TokenStream(string fieldName, TextReader reader)
    {
        return new WhitespaceAndAtSymbolTokenizer(reader);
    }
}

هذا كل شيء!الآن تحتاج فقط إلى إعادة بناء الفهرس الخاص بك وإجراء جميع عمليات البحث باستخدام هذا المحلل الجديد.على سبيل المثال، لكتابة المستندات إلى الفهرس الخاص بك:

IndexWriter index = new IndexWriter(indexDirectory, new WhitespaceAndAtSymbolAnalyzer());
index.AddDocument(myDocument);

يجب أن يستخدم إجراء عمليات البحث المحلل أيضًا:

IndexSearcher searcher = new IndexSearcher(indexDirectory);
Query query = new QueryParser("TheFieldNameToSearch", new WhitespaceAndAtSymbolAnalyzer()).Parse("@gmail.com");
Hits hits = query.Search(query);

نصائح أخرى

أرى أن لديك الحل الخاص بك، ولكن الحل الخاص بي كان سيتجنب هذا ويضيف حقلاً إلى المستندات التي تقوم بفهرستها يسمى email_domain، والذي كنت سأضيف إليه المجال الذي تم تحليله لعنوان البريد الإلكتروني.قد يبدو الأمر سخيفًا، لكن مقدار التخزين المرتبط بهذا ضئيل جدًا.إذا كنت ترغب في أن تصبح أكثر روعة، فلنفترض أن بعض النطاقات تحتوي على العديد من النطاقات الفرعية، يمكنك بدلاً من ذلك إنشاء حقل يذهب إليه النطاق المعكوس، بحيث يمكنك تخزين com.gmail أو com.company.department أو ae.eim حتى تتمكن من العثور عليه جميع العناوين ذات الصلة بدولة الإمارات العربية المتحدة مع الاستعلام بالبادئة "ae".

هناك أيضا setAllowLeadingWildcard

ولكن يجب حذر.قد يكون هذا مكلفًا جدًا للأداء (ولهذا السبب يتم تعطيله افتراضيًا).ربما يكون هذا حلاً سهلاً في بعض الحالات، لكنني أفضل استخدام Tokenizer مخصصًا كما ذكر يهوذا هيمانجو, ، أيضاً.

يمكنك إنشاء حقل منفصل يقوم بفهرسة عنوان البريد الإلكتروني المعكوس:فهرس 'foo@gmail.com' باسم "moc.liamg@oof" الذي يمكّنك من إجراء استعلام لـ "moc.liamg@*"

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