Grails поиск плагина запрос
Приложение My Grails использует плагин с возможностью поиска, который основан на Compass и Lucene для обеспечения функциональности поиска. У меня есть два класса поиска, скажем, Автор и Книга. Я сопоставил эти классы с поисковым индексом, чтобы можно было искать только определенные поля.
Чтобы выполнить поиск по обоим классам, я просто звоню
def results = searchableService.search(query)
Одной из приятных особенностей одновременного поиска в обоих классах является то, что results
объект включает метаданные о количестве включенных результатов, количестве доступных результатов, подробностях разбивки на страницы и т. д.
Я недавно добавил логическое значение approved
установите флажок для класса Книги, и я не хочу, чтобы в результатах поиска появлялись неутвержденные книги. Один из вариантов - заменить вышеуказанный вызов следующим:
def bookResults = Book.search(query + " approved:1")
def authorResults = Author.search(query)
Однако теперь мне нужно выяснить, как объединить метаданные для обоих результатов, что может быть сложно (особенно разбиение на страницы).
Есть ли способ поиска по Книге и Автору с помощью одного запроса, но только возврат утвержденных книг?
2 ответа
Я создал тестовое приложение и пришел к следующему решению. может это поможет...
если собственность 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)"
)
Хотите ли вы найти авторов или книги с данным автором?
Если вы хотите найти книги с указанным автором, вы можете настроить классы своего домена следующим образом:
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
с, это может работать для вас.