6

我的 Grails 应用程序正在使用可搜索插件,它建立在 Compass 和 Lucene 之上以提供搜索功能。我有两个可搜索的类,比如 Author 和 Book。我已将这些类映射到搜索索引,因此只能搜索某些字段。

要在两个类中执行搜索,我只需调用

def results = searchableService.search(query)

同时在两个类中进行搜索的一个很好的特性是,该results对象包含有关包含的结果数量、可用结果数量、分页详细信息等的元数据。

我最近approved在 Book 类中添加了一个布尔标志,我不希望未经批准的书籍出现在搜索结果中。一种选择是将上面的调用替换为:

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

但是,我现在需要弄清楚如何组合两个结果的元数据,这可能很棘手(尤其是分页)。

有没有办法通过单个查询搜索图书和作者,但只返回批准的图书?

4

2 回答 2

6

您希望能够找到作者,还是想找到给定作者的书籍?

如果要查找具有给定作者的书籍,可以通过以下方式配置域类:

class Author {
    String name
    ...

    static searchable = {
        root false
    }    
}

这将导致从searchableService.search(query)-result 中排除作者,您会$/Book/Author/name在索引中找到类似的字段名称。(使用卢克检查您的索引:http ://code.google.com/p/luke/ )。

prefix您可以通过在 Book-class 中配置更好的方法来更改这些字段的名称:

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.totals,这可能对您有用。

于 2012-01-12T21:00:12.320 回答
4

我创建了一个测试应用程序并得出以下解决方案。也许它有帮助......

如果该属性approved只有状态01,则以下查询将起作用:

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)"
)
于 2012-01-19T22:05:36.190 回答