2013-04-23 80 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

相關問題