2012-01-10 16 views
6

La aplicación My Grails está utilizando el complemento de búsqueda, que se basa en Compass y Lucene para proporcionar funcionalidad de búsqueda. Tengo dos clases de búsqueda, dicen Autor y Libro. He asignado estas clases al índice de búsqueda, de modo que solo se puedan buscar ciertos campos.solicitud de complemento de búsqueda de grails

para realizar una búsqueda a través de ambas clases Simplemente llamo

def results = searchableService.search(query) 

Una de las características interesantes de hacer la búsqueda a través tanto de clase al mismo tiempo, es que el objeto results incluye metadatos sobre el número de resultados incluidos, número de resultados disponibles, detalles de paginación, etc.

Recientemente agregué una bandera booleana approved a la clase Libro y nunca quiero que los libros no aprobados aparezcan en los resultados de búsqueda. Una opción es reemplazar la llamada anterior con:

def bookResults = Book.search(query + " approved:1") 
def authorResults = Author.search(query) 

Sin embargo, ahora la necesidad de encontrar la manera de combinar los metadatos para ambos resultados, lo cual es probable que sea difícil (sobre todo la paginación).

¿Hay alguna manera de buscar entre Libro y Autor con una sola consulta, pero solo devolver libros aprobados?

Respuesta

4

He creado una aplicación de prueba y he llegado a la siguiente solución. tal vez esto ayuda ...

si la propiedad approved solamente tiene los estados 0 y 1, la siguiente consulta funcionará:

def results = searchableService.search(
    "(${query} AND approved:1) OR (${query} -approved:0 -approved:1)" 
) 

supongo que esto puede reformularse de una mejor manera si no lo hace use QueryParser pero BooleanQueryBuilder.

Por cierto: si se agrega un método como

String getType() { "Book" } 

y

String getType() { "Author" } 

Para sus dominios, incluso se puede configurar su búsqueda a hacerlo de esta manera

def results = searchableService.search(
    "(${query} AND approved:1) OR (${query} AND type:Author)" 
) 
+0

Admiro tu persistencia. La solución anterior parece funcionar, ¡muchas gracias! –

+0

:-) esperaba capturar la recompensa ... – rdmueller

6

¿Desea poder encontrar autores o desea buscar libros con un autor determinado?

Si usted quiere encontrar libros con un autor determinado, puede configurar sus clases de dominio de la siguiente manera:

class Author { 
    String name 
    ... 

    static searchable = { 
     root false 
    }  
} 

esto resultará en la exclusión del autor de la searchableService.search(query) -resultado y encontrará nombres de campo como $/Book/Author/name en su índice. (use luke para examinar su índice: http://code.google.com/p/luke/).

Puede cambiar el nombre de los campos mediante la configuración de una mejor prefix en su libro de clase:

class Book { 
    String name 
    Author author 
    ... 

    static searchable = { 
     author component: [prefix: 'author'] 
    }  
} 

esto va a cambiar el nombre del campo en el índice de bookauthor.

Si ahora busca con searchableService.search(query), encontrará todos los libros donde el nombre del libro o el nombre del autor contiene el término de búsqueda. Incluso puede restringir la búsqueda a un autor determinado utilizando la sintaxis authorname:xyz.


Si realmente quisiera mezclar los resultados de la búsqueda, sólo sé la solución que ya se ha mencionado: Mezcla de los resultados con su propio código, pero supongo que será difícil de mezclar la puntuación de los éxitos en una buena manera.

actualización de su respuesta: Aquí está mi código de la paginación ...

.gsp:

<div class="pagination"> 
    <g:paginate total="${resultsTotal}" params="[q: params.q]"/> 
</div> 

controlador:

result = searchableService.search(params.q, params) 
[ 
    resultList: result.results, 
    resultsTotal: result.total 
] 

Así que si usted acaba de combinar los resultados de sus dos búsquedas y agregue el result.total s, esto podría funcionar para usted.

+0

Quiero ser capaz de encontrar libros y autores con una sola consulta, pero nunca incluir b no aprobado Ooks en los resultados. El problema con hacer 2 consultas es que es difícil combinar los 2 conjuntos de metadatos en un solo conjunto. Por ejemplo, si tengo 2 páginas de resultados de libros y 2 páginas de resultados de autores, eso no significa necesariamente que tengo 4 páginas de resultados en total –

+0

Lo siento, creo que echo de menos algo aquí. No es el caso si tiene 15 resultados de libros y 17 de autor, siempre tendrá 32 resultados juntos -> 4 páginas (con 10 resultados cada uno) – rdmueller

+0

Sí, pero si tengo 11 resultados de libros (2 páginas) y 11 resultados de autor (2 páginas); luego, si combino los resultados, puedo incluirlos en 3 páginas. –

Cuestiones relacionadas