簡體   English   中英

Grails lucene搜索耗費大量時間

[英]Grails lucene search taking inordinate amount of time

對於背景,我在我的應用程序中使用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]

與Compene相比,與Lucene相比,這似乎是一個更大的問題,因為查詢執行速度很快,但是Compass映射將Java進程的CPU占用率接近100%,並且掛起的時間太長了。

我已為大約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]
    }

}

任何想法將不勝感激。 這是我的一個自學項目,我真的想以正確的方式進行搜索。 :)謝謝,凱文

在我正在開發的最新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的缺點是,結果將不包含從索引解組的對象,並且您必須使用作為搜索結果一部分返回的ID從數據庫中獲取匹配的域對象。 您可能會認為這很糟糕,但事實並非如此,使用這種方法,我的搜索結果實際上比以前更快地顯示。 這是有關設置supportUnmarshall選項http://grails.org/Searchable+Plugin+-+Mapping+-+Class+Mapping的信息的URL。 它是“選項”部分中的最后一個選項。

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可搜索插件的網頁,並查找有關如何安裝可搜索配置插件的文檔。

舉例說明性能改進。 以前,對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]
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM