2010-04-28 20 views
9

Estoy usando Lucene.Net 2.0 para indexar algunos campos de una tabla de base de datos. Uno de los campos es un campo 'Nombre' que permite caracteres especiales. Cuando realizo una búsqueda, no encuentra mi documento que contiene un término con caracteres especiales.Lucene y caracteres especiales

índice I mi campo como tal:

Directory DALDirectory = FSDirectory.GetDirectory(@"C:\Indexes\Name", false); 
Analyzer analyzer = new StandardAnalyzer(); 
IndexWriter indexWriter = new IndexWriter(DALDirectory, analyzer, true, IndexWriter.MaxFieldLength.UNLIMITED); 

Document doc = new Document(); 
doc.Add(new Field("Name", "Test (Test)", Field.Store.YES, Field.Index.TOKENIZED)); 
indexWriter.AddDocument(doc); 

indexWriter.Optimize(); 
indexWriter.Close(); 

y busco hacer lo siguiente:

value = value.Trim().ToLower(); 
value = QueryParser.Escape(value); 

Query searchQuery = new TermQuery(new Term(field, value)); 
Searcher searcher = new IndexSearcher(DALDirectory); 

TopDocCollector collector = new TopDocCollector(searcher.MaxDoc()); 
searcher.Search(searchQuery, collector); 
ScoreDoc[] hits = collector.TopDocs().scoreDocs; 

Si realizo una búsqueda para el campo como 'Nombre' y valor como 'prueba', encuentra el documento. Si realizo la misma búsqueda que 'Nombre' y el valor como 'Prueba (Prueba)', entonces no encuentra el documento.

Aún más extraño, si elimino la línea QueryParser.Escape hago una búsqueda de un GUID (que, por supuesto, contiene guiones) encuentra documentos donde coincide el valor GUID, pero realiza la misma búsqueda con el valor ' Test (Test) 'todavía no arroja resultados.

No estoy seguro de lo que estoy haciendo mal. Estoy usando el método QueryParser.Escape para escapar de los caracteres especiales y estoy almacenando el campo y buscando en los ejemplos de Lucene.Net.

¿Alguna idea?

Respuesta

5

StandardAnalyzer quita los caracteres especiales durante la indexación. Puede pasar una lista de palabras vacías explícitas (excluyendo las que desea).

+0

¿Debo considerar utilizar otro analizador para lograr mi objetivo? ¿Qué hay de cambiar entre Tokenized a Un_Tokenized cuando almacena campos con caracteres especiales? – Brandon

+0

bien si no tokenize el campo no puede "buscar" en él. Tiene un par de opciones para escribir su propio analizador (es muy simple) o pasar la lista de palabras de finalización al StandardAnalyzer. algo así como: Hashtable htStopwords = new Hashtable(); Analyzer analyzer = new StandardAnalyzer (htStopwords); – Mikos

+0

también puede ver StopAnalyzer o SimpleAnalyzer ... podrían ayudar. El problema es que podrías terminar teniendo muchas palabras ruidosas. Pero si eso no es un problema ... – Mikos

3

Mientras indexa, ha tokenizado el campo. Por lo tanto, su cadena de entrada crea dos tokens "prueba" y "prueba". Para la búsqueda, está construyendo consultas a mano, es decir, utilizando TermQuery en lugar de QueryParser, que habría tokenizado el campo.

Para la coincidencia completa, debe indizar el campo UN_TOKENIZED. Aquí, la cadena de entrada se toma como un único token. El token único creado "Prueba (Prueba)". En ese caso, su código de búsqueda actual funcionará. Debe observar cuidadosamente el caso de la cadena de entrada para asegurarse de que si está indexando texto en minúscula, debe hacer lo mismo durante la búsqueda.

En general, es una buena práctica usar el mismo analizador durante la indexación y la búsqueda. Puede usar KeywordAnalyer para generar un único token a partir de la cadena de entrada.