Я уже некоторое время возился с 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
или что-то еще.