Никто не дал удовлетворительного ответа, поэтому мы начали осматривать документацию 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);