Grail query to search

My Grails uses a search plugin that builds on Compass and Lucene to provide search functionality. I have two classes available for search, for example, author and book. I matched these classes with a search index, so that you can only search for specific fields.

To search for both classes, I simply call

def results = searchableService.search(query) 

One of the great features of performing searches on both classes at the same time is that the results object includes metadata about the number of included results, the number of available results, detailed data, etc.

I recently added a logical approved flag to the Book class, and I never want unapproved books to appear in search results. One option is to replace the call above:

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

However, now I need to figure out how to combine metadata for both results, which may seem complicated (especially pagination).

Is there a way to search through a book and an author with a single request, but only return approved books?

+6
source share
2 answers

I created a test application and came to the next solution. maybe this helps ...

if the approved property has only states 0 and 1 , the following request will work:

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

I assume that this can be reformulated better if you do not use QueryParser, but BooleanQueryBuilder.

BTW: if you add a type method

 String getType() { "Book" } 

and

 String getType() { "Author" } 

In your domains, you can customize your search in a way

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

Do you want to find authors or do you want to find books with this author?

If you want to find books with this author, you can configure the domain classes as follows:

 class Author { String name ... static searchable = { root false } } 

this will cause the author to be excluded from searchableService.search(query) -result, and you will find field names such as $/Book/Author/name in your index. (use luke to view your index: http://code.google.com/p/luke/ ).

You can change the name of these fields by setting up the best prefix in your Book class:

 class Book { String name Author author ... static searchable = { author component: [prefix: 'author'] } } 

this will change the name of the field in the index to bookauthor .

If you now search using searchableService.search(query) , you will find all books in which the book name or author name contains a search query. You can even limit the search to a given author using the syntax authorname:xyz .


If you really want to mix search results, I only know the solution that you already mentioned: mixing both results with your own code, but I think it will be difficult to mix hit counts in a good way.

Update your answer: Here is my pagination code ...

.gsp:

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

controller:

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

So, if you just combine the results of your two searches and add result.total s, this might work for you.

+6
source

Source: https://habr.com/ru/post/905607/


All Articles