2013-04-23 84 views
1

对于背景,我使用Grails v2.2.1和可搜索插件(v0.6.4)作为我的应用程序,尽管我是配置Lucene的新手。Grails 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]

这似乎是与北斗比Lucene的作为更成问题查询执行速度很快,但Compass映射在我的Java进程接近100%的CPU时挂起,并且挂起的时间太长。

我有大约3500个域对象编入索引,我的域模型如下所示: 我试图仅索引字段名称和ID,但它似乎映射了通过卢克看到的域中的所有内容。在我的控制器

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] 
    } 

} 

任何想法,将不胜感激。这是我的一个自学项目,我真的想以正确的方式进行搜索。 :)谢谢, Kevin

+0

你可以发布你的搜索代码? – allthenutsandbolts 2013-04-24 16:55:26

+0

确定我会更新我的问题。 – vinberts 2013-04-24 18:23:24

+0

我没有看到任何明显的。你可以尝试在bootstrap中使用searchableService.reindex() ,看看是否有帮助 – allthenutsandbolts 2013-04-24 19:50:42

回答

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可搜索插件中内置的Compass功能有关。

作为搜索的一部分,所有匹配的对象被编组到索引中。对于100年代的一组Domain对象来说,执行这个编组的时间并不算太糟,但是,当你进入1000年的时候,这需要大量的时间。也许时间也与编组对象的复杂性有关?无论如何,我发现了一个和我有类似问题的人的博客文章。

http://webcache.googleusercontent.com/search?q=cache:lebHKgX2yXUJ:blog.hououji.info/archives/165+&cd=10&hl=en&ct=clnk&gl=us

总结时,他正在寻找的文章1000+对象的搜索时间的15秒。就像我所经历的一样。

他提到了两两件事:

1)设置“supportUnmarshall”选项设置为false,默认值是true,在域对象的“静态搜索”的配置。通过设置此选项,搜索匹配不会编入索引,但搜索时间非常快。如果将此选项设置为false,则结果将不包含从Index解组的对象,并且必须使用作为搜索结果的一部分返回的ID从数据库中获取匹配的域对象。你会认为这会很糟糕,但事实并非如此,使用这种方法我的搜索结果实际上比以前显示得更快。以下是有关设置supportUnmarshall选项 http://grails.org/Searchable+Plugin+-+Mapping+-+Class+Mapping的信息的URL。这是“选项”部分的最后一个选项。

2)在Searchable.groovy配置文件的defaultMethodOptions中启用“reload”。所以把这样的事情在Searchable.groovy文件:

defaultMethodOptions = [ 
    search: [reload: true, escape: false, offset: 0, max: 25, defaultOperator: "and"], 
    suggestQuery: [userFriendly: true] 
] 

您将需要添加检索配置插件更新此值。添加和编辑Searchable.groovy配置文件的详细信息可以在Grail可搜索插件的网页上找到。因为我的声望不够高。我不能发布两个以上的链接,因此您需要访问Grails可搜索插件的网页,并查找关于如何安装Searchable Config Plugin的文档。

举例说明性能改进。以前,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] 
} 
+0

我必须尝试一下!感谢您的详细解答/回复。 – vinberts 2014-03-27 14:07:23

相关问题