2010-03-09 7 views
6

Cada documento de Lucene es una receta, y cada una de estas recetas tiene ingredientes.Índice de Lucene con campos múltiples de la misma naturaleza

Estoy trabajando para poder buscar los ingredientes y dar un resultado que diga dos ingredientes combinados de cuatro. (por ejemplo)

Entonces, ¿cómo puedo agregar los ingredientes al documento? En Solr puedo crear múltiples campos de y los salvaría a todos, podría estar haciendo algo mal porque solo guarda el ingrediente.

También esto se aplicaría a un campo como 'etiquetas'.

p.s Im usando el Zend Framework para esto, si es que importa.

Respuesta

12

Los documentos de Lucene admiten la adición de múltiples campos con el mismo nombre. es decir, se puede llamar en repetidas ocasiones:

document.add(new Field("name"), value) 

Así eran que hagas:

# (pseudo-code) 
document1.add(new Field("ingredient"), "vanilla") 
document1.add(new Field("ingredient"), "strawberry") 
index.add(document) 

# And then search for 
index.search("ingredient", "vanilla" && "strawberry") 

Va a volver documento1. Pero si se busca:

index.search("ingredient", "vanilla" && "apple") 

Usted no va a volver documento1.

Si buscado:

index.search("ingredient", "vanilla" || "apple") 

También tendría que volver documento1.

Si desea ver qué ingredientes coinciden puede simplemente guardar los campos en el documento como Almacenado campos, y luego para cada documento coincidente recuperar la lista de campos y compararlos con la consulta del usuario.

También tenga en cuenta que, de forma predeterminada, PositionIncrementGap para los campos con el mismo nombre que se agregan a un documento es 0.

Esto significa que si se ha añadido:

document1.add(new Field("ingredient"), "chocolate") 
    document1.add(new Field("ingredient"), "orange") 

entonces sería tratada como si se tratara de un único ingrediente llamado "chocolate de naranja", que podría coincidir en:

index.search("ingredient", "chocolate orange") 

Usted puede evitar este conjunto un valor para PositionIncrementGap> 1, lo que dió:

0 coincidencias para:

index.search("ingredient", "chocolate orange") 

y 1 resultado para:

index.search("ingredient", "chocolate" && "orange") 
0

Veo dos enfoques posibles aquí:

  1. Desnormalizar sus datos - crear un documento separado para cada ingrediente en una receta, dando todos los documentos para una receta un identificador de receta común. Luego, durante la búsqueda, agregue todas las coincidencias de una ID de receta. Un poco feo
  2. Concatenar todos sus ingredientes en un campo común e indexarlo como 'Texto'. Luego busque los ingredientes usando una consulta booleana con 'OR' (Esto se llama 'Should' en términos de Java Lucene, no conozco el equivalente de PHP).

Le sugiero que pruebe el segundo enfoque y vea si ayuda.

Cuestiones relacionadas