对于后台,我使用Grails v2.2.1和Searchable插件(v0.6.4)作为我的应用程序,虽然我在配置Lucene时是新手。
日志显示搜索需要26毫秒,但罗盘交易大约需要15秒才能返回:
2013-04-23 00:40:34,269 DEBUG grails.plugin.searchable.internal.
compass.search.DefaultSearchMethod - query: [+kind:band +name:snoop], [4] hits, took [26] millis
2013-04-23 00:40:49,965 DEBUG org.compass.core.transaction.LocalTransaction - Committing local transaction on thread [http-bio-8080-exec-10] Compass [1176020804] Session [2089649487]
这似乎是Compass而不是Lucene的一个问题,因为查询执行得很快,但Compass映射将我的Java进程固定在接近100%的CPU并且挂起的时间太长。
我有大约3500个域对象被索引,我的域模型如下所示: 我试图只索引字段名称和id,但它似乎通过Luke看到了域中的所有内容。
package com.bandbot
class Band {
def slugGeneratorService
static searchable = {
mapping {
spellCheck "exclude"
only: ['name', 'id']
}
}
String name
String biography
String profileImage
String slug
String similarBands // this will store bands/url/pic in the form of Kanye West::url::img.png~Queen::url::img.png
boolean onTour // is this band currently touring? (Info from lastfm)
String mbid // This band's MusicBrainz ID see @ http://musicbrainz.org/doc/MusicBrainz_Identifier
String bandUrl
String lastFMUrl // stores the lastfm url
Date dateOfInception
Date dateDisbanded
Date lastUpdated
static belongsTo = [Genre, BandbotUser]
static hasMany = [ events : Event, genres : Genre ]
def beforeInsert() {
lastUpdated = new Date()
this.slug = slugGeneratorService.generateSlug(this.class, "slug", name)
}
def beforeUpdate() {
lastUpdated = new Date()
if (isDirty('name')) {
this.slug = slugGeneratorService.generateSlug(this.class, "slug", name)
}
}
static constraints = {
name(nullable: false, blank: false, unique: true)
slug(nullable: true)
bandUrl(nullable: true)
dateDisbanded(nullable: true)
mbid(nullable: true)
dateOfInception(nullable: true)
biography(nullable: true)
similarBands(nullable: true)
lastUpdated(nullable: true)
lastFMUrl(nullable: true)
kind( display: false )
}
static mapping = {
onTour defaultValue: false
biography type: 'text'
similarBands type: 'text'
}
String toString(){name}
}
我的控制器中的搜索逻辑用于乐队:
def search() {
if (!params.q?.trim()) {
return [:]
}
try {
def searchResult
if (params.sort) {
searchResult = searchableService.search(
params.q.trim(),
[offset: params.offset ? params.int('offset') : 0,
max: params.max ? params.int('max') : 10,
sort: params.sort, order: params.order? params.order : 'asc']
)
}
else {
searchResult = searchableService.search(
params.q.trim(),
[offset: params.offset ? params.int('offset') : 0,
max: params.max ? params.int('max') : 10]
)
}
return [searchResult: searchResult, params: params]
} catch (SearchEngineQueryParseException ex) {
return [parseException: true, params: params]
}
}
任何想法都将不胜感激。这是我的自学项目,我真的想以正确的方式进行搜索。 :) 谢谢, 凯文
答案 0 :(得分:2)
我在最近开发的Grails应用程序中使用可搜索的插件时遇到了同样的问题。我有两个域对象,具有一对多的关系,我正在索引进行搜索。为简单起见,我只是显示Domain对象及其字段和关系。我没有显示任何映射或约束信息。这是我原来的课程
class CodeValue{
static searchable ={
only:['value', 'description']
value boost: 2.0
}
String value
String description
static belongsTo = [codeset: CodeSet]
}
class CodeSet{
static searchable ={
only:['name', 'description']
name boost: 2.0
}
String name
String description
static hasMany = [codeValues:CodeValue]
}
搜索CodeValues> 17秒我确实有超过1000个CodeValue对象被索引,但是17秒的搜索时间是不可接受的。我找出导致搜索时间慢的原因,它似乎与Grails Searchable插件中内置的Compass功能有关。
作为搜索的一部分,所有匹配的对象都被编组到索引中。对于100中的一组Domain对象,执行此编组的时间并不算太差,但是,当你进入1000时,它需要花费大量的时间。也许时间也与正在编组的对象的复杂性有关?无论如何,我发现了一个与我有类似问题的人的博客文章。
总结一篇文章,当他搜索1000多个对象时,搜索时间大于15秒。就像我遇到的那样。
他提到了两件事:
1)设置" supportUnmarshall"选项为false,默认值为true,在域对象的“静态可搜索”配置中。通过设置此选项,搜索匹配不会编组到索引中,但搜索时间非常快。将此选项设置为false的下降是结果将不包含从索引中解组的对象,并且您必须使用作为搜索结果的一部分返回的id从数据库中获取匹配的域对象。你会认为这会很糟糕,但事实并非如此,并且使用这种方法我的搜索结果实际上显示得比以前快得多。以下是有关设置supportUnmarshall选项的信息的URL http://grails.org/Searchable+Plugin+-+Mapping+-+Class+Mapping。这是“选项”部分中的最后一个选项。
2)启用"重新加载"在Searchable.groovy配置文件的defaultMethodOptions中。所以在Searchable.groovy文件中输入这样的内容:
defaultMethodOptions = [
search: [reload: true, escape: false, offset: 0, max: 25, defaultOperator: "and"],
suggestQuery: [userFriendly: true]
]
您需要添加Searchable Config插件才能更新此值。有关添加和编辑Searchable.groovy配置文件的详细信息,请参阅Grail Searchable插件的网页。由于我没有足够高的声誉。我不能发布两个以上的链接,因此您需要访问Grails Searchable插件的网页,并查看有关如何安装Searchable Config插件的文档。
举一个性能改进的例子。以前,对CodeValues的搜索需要17秒以上才能完成。它们现在在0.002秒内完成。
我写的最终代码如下:
class CodeValue{
static searchable ={
only:['value', 'description']
value boost: 2.0
supportUnmarshall false
}
String value
String description
static belongsTo = [codeset: CodeSet]
}
class CodeSet{
static searchable ={
only:['name', 'description']
name boost: 2.0
supportUnmarshall false
}
String name
String description
static hasMany = [codeValues:CodeValue]
}