2010-01-13 17 views
8

¿Cómo hago una "O" en Lucene.NET. Básicamente, lo que tengo es una matriz de ID y quiero devolver cualquier registro donde un campo en particular contenga alguno de los valores. Anteriormente estaba haciendo esto con un solo valor, pero ahora quiero convertir el siguiente código para que MetaDataID sea una matriz de valores posibles en lugar de un único valor.Lucene.NET "O"

if (MetaDataID.Length > 0) 
    completeQuery.Add(new QueryParser("MetaData", new StandardAnalyzer()).Parse(MetaDataID), BooleanClause.Occur.MUST); 

Respuesta

4

Es necesario utilizar BooleanClause.Occur.SHOULD en lugar de BooleanClause.Occur.MUST

ej .:

BooleanQuery booleanQuery = new BooleanQuery(); 
Query query1 = new TermQuery(new Term("id", "<id 1>")); 
Query query2 = new TermQuery(new Term("id", "<id 2>")); 
booleanQuery.add(query1, BooleanClause.Occur.SHOULD); 
booleanQuery.add(query2, BooleanClause.Occur.SHOULD); 
+0

esto no parece devolver el conjunto A | B. Cuando intento esto obtengo todos los registros que coinciden con la otra cláusula DEBE. Es decir, parece que los DEBERES están siendo ignorados. – Kyle

+1

No estoy muy seguro de que te entendamos. Pero creo que lo que debes hacer es anidar tus BooleanQueries. –

+0

'Necesita usar bla ...', pero ¿por qué? –

2

Tenga cuidado al usar BooleanQuery para recuperar documentos de identificación, ya que tiene un límite máximo de las cláusulas booleanos.

La base "o" cláusula en Lucene se realiza de esta manera, suponiendo que su campo de búsqueda se denomina "id":

"id: 1 id: 2 id: 3 id: 4"

en lugar de una "y" consulta:

"+ id: 1 + id: 2 + id: 3 + id: 4"

Utilizando el estándar QueryParser y una StringBuilder debe hacer la magia para usted.

3

Cuando realmente quiere analizar su consulta, solo tiene que elegir el analizador y el formato correctos para su consulta.

El StandardAnalyzer no es una buena opción cuando indexa cualquier cosa excepto el texto completo en inglés, ¡especialmente no en su caso! ¡Filtra los números!

La solución más corta en su caso es crear un analizador que se una en un separador y combine su objeto en una cadena.

Ejemplo:

Crear un Tokenizer que se divide en separadores típicos y un analizador que utiliza

using System.IO; 
using System.Linq; 
using Lucene.Net.Analysis; 

namespace Project.Analysis 
{ 
    public class TermTokenizer : LetterTokenizer 
    { 
     // some static separators 
     private static readonly char[] NONTOKEN_CHARS = new char[] { ',', ';', ' ', '\n', '\t' }; 

     protected override bool IsTokenChar(char c) 
     { 
      return !NONTOKEN_CHARS .Contains(c); 
     } 
    } 

    public class LowerCaseTermAnalyzer : Analyzer 
    { 
     public override TokenStream TokenStream(string fieldName, TextReader reader) 
     { 
      return new LowerCaseFilter(new TermTokenizer(reader)); 
     } 
    } 
} 

uso del nuevo analizador en su analizador

(Usted necesita incluir System.Linq)

if (MetaDataID.Length > 0) 
{ 
    // the search term will look like this: "1;5;7" 
    string searchTerm = string.Join(";", MetaDataID); 

    // the query parser uses the new Analyzer 
    QueryParser parser = new QueryParser("MetaData",new LowerCaseTermAnalyzer()); 

    // the parsed search term (only used internally) will look like this: 
    // "MetaData:1 MetaData:5 MetaData:7", which is essentially what you want to achieve 
    completeQuery.Add(new parser.Parse(MetaDataID), BooleanClause.Occur.MUST); 
} 
10

Al combinar consultas de Lucene en las que desea cualquier registro de índice que contenga cualquiera de los múltiples valores posibles con criterios adicionales que también deben cumplirse, cree múltiples objetos de consulta booleanos.

Para el primer grupo de "o" condiciones:

BooleanQuery booleanQueryInner = new BooleanQuery(); 
Query query1 = new TermQuery(new Term("id", "<id 1>")); 
Query query2 = new TermQuery(new Term("id", "<id 2>")); 
Query query3 = new TermQuery(new Term("id", "<id 3>")); 
Query query4 = new TermQuery(new Term("id", "<id 4>")); 
booleanQueryInner.add(query1, BooleanClause.Occur.SHOULD); 
booleanQueryInner.add(query2, BooleanClause.Occur.SHOULD); 
booleanQueryInner.add(query3, BooleanClause.Occur.SHOULD); 
booleanQueryInner.add(query4, BooleanClause.Occur.SHOULD); 

Ahora se combinan con otras condiciones en la consulta

BooleanQuery booleanQueryOuter = new BooleanQuery(); 
booleanQueryOuter.add(booleanQueryInner, BooleanClause.Occur.MUST); 
booleanQueryOuter.add(boolenaQueryOtherConditions, BooleanClause.Occur.MUST); 

Ahora sólo serán devueltos registros de índice si cumplen una de las condiciones en el grupo "O" interno y también cumple las condiciones en la consulta "otras condiciones".