Uso de Lucene para buscar direcciones de correo electrónico


5

Quiero usar Lucene (en particular, Lucene.NET) para buscar dominios de direcciones de correo electrónico.

E.g. Quiero buscar "@ gmail.com" para encontrar todos los correos electrónicos enviados a una dirección de Gmail.

Al ejecutar una consulta de Lucene para "*@gmail.com" se produce un error, los asteriscos no pueden estar al inicio de las consultas. La ejecución de una consulta para "@ gmail.com" no devuelve ninguna coincidencia, porque "[email protected]" se ve como una palabra completa, y no puede buscar solo partes de una palabra.

¿Cómo puedo hacer esto?

10

Nadie dio una respuesta satisfactoria, por lo que comenzamos a hurgar en la documentación de Lucene y descubrimos que podemos lograr esto utilizando Analizadores y Tokenizadores personalizados.

La respuesta es la siguiente: cree un WhitespaceAndAtSymbolTokenizer y un WhitespaceAndAtSymbolAnalyzer, luego vuelva a crear su índice con este analizador. Una vez que hagas esto, una búsqueda de "@ gmail.com" devolverá todas las direcciones de Gmail, ya que se ve como una palabra separada gracias al Tokenizer que acabamos de crear.

Aquí está el código fuente, en realidad es muy simple:

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); 
    } 
} 

eso es todo! Ahora solo necesita reconstruir su índice y hacer todas las búsquedas usando este nuevo Analizador. Por ejemplo, para escribir documentos en el índice:

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

búsquedas escénicas deben utilizar el analizador, así:

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

También pasaría el tokenizer a través de un LowerCaseFilter, o quizás un CustomCaseFilter personalizado que solo minería el token de @GmAil.COM 07 may. 142014-05-07 06:33:45


5

veo que tiene su solución, pero la mía habría evitado este y ha añadido un campo a los documentos que está indexando llamados email_domain, en los que habría agregado el dominio analizado de la dirección de correo electrónico. Puede sonar tonto, pero la cantidad de almacenamiento asociado con esto es bastante mínimo. Si te apetece ser más elegante, por ejemplo, algunos dominios tienen muchos subdominios, en su lugar puedes crear un campo al que pertenece el dominio invertido, por lo que almacenarías com.gmail, com.company.department o ae.eim para que puedas encontrar todas las direcciones relacionadas con los Emiratos Árabes Unidos con una consulta de prefijo de 'ae'.


0

Es posible que un campo separado que indexa la dirección de correo electrónico invierten: Índice '[email protected]' como '[email protected]' que le permite hacer una consulta para "[email protected]*"

  0

Hmm. Eso suena realmente hackish. 05 oct. 082008-10-05 21:15:13


2

también hay setAllowLeadingWildcard

Pero tenga cuidado . Esto podría hacer que el rendimiento sea muy caro (por eso está deshabilitado por defecto). Tal vez en algunos casos esta sea una solución fácil, pero preferiría un Tokenizer personalizado según lo establecido por Judah Himango, también.