Grails поиск плагина запрос - PullRequest
6 голосов
/ 10 января 2012

Приложение My Grails использует плагин с возможностью поиска, который основан на Compass и Lucene для обеспечения функциональности поиска. У меня есть два класса поиска, скажем, Автор и Книга. Я сопоставил эти классы с индексом поиска, чтобы можно было искать только определенные поля.

Чтобы выполнить поиск по обоим классам, я просто звоню

def results = searchableService.search(query)

Одной из приятных особенностей одновременного выполнения поиска по обоим классам является то, что объект results включает метаданные о количестве включенных результатов, количестве доступных результатов, подробностях разбивки на страницы и т. Д.

Недавно я добавил логический флаг approved в класс Book и не хочу, чтобы в результатах поиска появлялись неутвержденные книги. Один из вариантов - заменить вышеуказанный вызов на:

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

Однако теперь мне нужно выяснить, как объединить метаданные для обоих результатов, что может быть сложно (особенно разбиение на страницы).

Есть ли способ поиска по Книге и Автору с помощью одного запроса, но только для возврата утвержденных книг?

Ответы [ 2 ]

6 голосов
/ 13 января 2012

Хотите ли вы найти авторов или вы хотите найти книги с указанным автором?

Если вы хотите найти книги с указанным автором, вы можете настроить классы вашего домена следующим образом.way:

class Author {
    String name
    ...

    static searchable = {
        root false
    }    
}

это приведет к исключению Автора из searchableService.search(query)-результата, и вы найдете имена полей, такие как $/Book/Author/name в вашем индексе.(используйте luke для проверки вашего индекса: http://code.google.com/p/luke/).

Вы можете изменить имя этих полей, настроив лучший prefix в вашем классе книг:

class Book {
    String name
    Author author
    ...

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

это изменитсяимя поля в индексе: bookauthor.

Если вы сейчас выполните поиск с помощью searchableService.search(query), вы найдете все книги, в которых название книги или имя автора содержит поисковый термин.Вы даже можете ограничить поиск данным автором, используя синтаксис authorname:xyz.


Если вы действительно хотите смешать результаты поиска, я знаю только решение, которое вы уже упомянули: смешивание обоихрезультаты с вашим собственным кодом, но я думаю, что будет сложно смешать оценку попаданий.

Обновление вашего ответа: Вот мой код нумерации страниц ...

.gsp:

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

контроллер:

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

Так что, если вы просто объедините результаты двух поисков и добавите result.total s, это может сработать для вас.

4 голосов
/ 20 января 2012

Я создал тестовое приложение и пришел к следующему решению. может быть, это поможет ...

если свойство approved имеет только состояния 0 и 1, будет работать следующий запрос:

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

Полагаю, это можно переформулировать лучше, если вы не используете QueryParser, а BooleanQueryBuilder.

Кстати: если вы добавите метод, такой как

String getType() { "Book" }

и

String getType() { "Author" }

Для ваших доменов вы даже можете настроить поиск так, чтобы это делалось так

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