Правильно токенизируйте электронную почту в Lucene.NET и по-прежнему сможете искать ее как полное слово - PullRequest
0 голосов
/ 09 июля 2019

Я уже некоторое время возился с Lucene.NET, и я просто не могу получить фильтры так, как я хочу. Главное, что мне нужно сделать, это то, что при индексации я хотел бы разделить слова, в то же время включив в индекс полное слово (которое я думал, что будет сделано с WordDelimiterFlags.PRESERVE_ORIGINAL, но я покажу вам, что у меня есть в во-вторых), затем я смогу найти эти слова, и, в частности, я надеюсь, что смогу искать электронные письма как полный адрес электронной почты, который я ввожу.

В настоящее время я использую два пользовательских анализатора:

При индексировании:

    public class MultiStageIndexAnalyzer : Analyzer
    {
        protected override TokenStreamComponents CreateComponents(string fieldName, TextReader reader)
        {
            var tokenizer = new WhitespaceTokenizer(LuceneVersion.LUCENE_48, reader);
            var lowercaseFilter = new LowerCaseFilter(LuceneVersion.LUCENE_48, tokenizer);
            var lowerAndDelimited = new WordDelimiterFilter(LuceneVersion.LUCENE_48, lowercaseFilter, WordDelimiterFlags.PRESERVE_ORIGINAL, null);

            return new TokenStreamComponents(tokenizer, lowerAndDelimited);
        }
    }

При поиске по электронной почте:

    public class CaseInsensitiveWhitespaceAnalyzer : Analyzer
    {
        protected override TokenStreamComponents CreateComponents(string fieldName, TextReader reader)
        {
            var tokenizer = new WhitespaceTokenizer(LuceneVersion.LUCENE_48, reader);
            var lowercaseFilter = new LowerCaseFilter(LuceneVersion.LUCENE_48, tokenizer);

            return new TokenStreamComponents(tokenizer, lowercaseFilter);
        }
    }

Я пробовал несколько разных WordDelimiterFlags, но ни один из них, кажется, не делает то, что я хочу. Если электронное письмо имеет адрес «test@email.com», то настройки, которые я нахожу, либо разбивают его на слова «test email com», то есть, если я пытаюсь выполнить поиск по полному электронному письму, которое не найдено, или оно сохраняет только электронную почту целое как "test@email.com", и если я ищу "электронная почта", оно не будет найдено.

Я не уверен, что могу показать намного больше, но вот где создается индекс:

    Analyzer analyzer = new MultiStageIndexAnalyzer();
    var config = new IndexWriterConfig(Lucene.Net.Util.LuceneVersion.LUCENE_48, analyzer);
    _indexWriter = new IndexWriter(dir, config);

И вот где выполняется поиск:

    var emailAnalyzer = new EmailOnlyAnalyzer();
    MultiFieldQueryParser emailParser = new MultiFieldQueryParser(
                    LuceneVersion.LUCENE_48,
                    new[] { "EmailTo", "EmailFrom", "EmailCC" }, emailAnalyzer)
    {
        DefaultOperator = QueryParser.AND_OPERATOR,
        AllowLeadingWildcard = true
    };
    var emailquery = emailParser.Parse(email);
    TopFieldCollector emailcollector = TopFieldCollector.Create(Sort.RELEVANCE, 100000, true, true, true, true);
    IndexSearcher indexSearcher = new IndexSearcher(indexReader);
    IndexSearcher indexEmailSearcher = new IndexSearcher(indexEmailReader);
    indexEmailSearcher.Search(emailquery, emailcollector);

Дайте мне знать, могу ли я добавить что-нибудь еще, чтобы прояснить ситуацию. Я просто не уверен, что я что-то упустил или неправильно использую WordDelimiterFilter или что-то еще.

...