1

背景として、私は自分のアプリケーションに 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]

これは、クエリがすばやく実行されるため、Lucene よりも Compass の問題のようですが、Compass マッピングは Java プロセスをほぼ 100% の CPU で固定し、長時間ハングします。

約 3500 のドメイン オブジェクトにインデックスが付けられており、ドメイン モデルは次のようになります。name フィールドと 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]
    }

}

どんなアイデアでも大歓迎です。これは私の自己学習プロジェクトのためのもので、正しい方法で検索したいと思っています。:) ありがとう、ケビン

4

1 に答える 1

2

私が開発していた最近の Grails アプリケーションで検索可能なプラグインを使用すると、同じ問題が発生しました。1 対多の関係を持つ 2 つのドメイン オブジェクトがあり、検索のためにインデックスを作成していました。簡単にするために、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 番台のドメイン オブジェクトのセットでは、このマーシャリングを実行する時間はそれほど悪くありませんが、1000 番台になるとかなりの時間がかかります。おそらく時間は、マーシャリングされるオブジェクトの複雑さに関係しているでしょうか? とにかく、私と同じような問題を抱えている人のブログ投稿を見つけました。

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

記事を要約すると、彼が 1000 個以上のオブジェクトを検索していたときの検索時間は 15 秒を超えていました。私が経験していたことと同じように。

彼は次の 2 つのことを述べました。

1) ドメイン オブジェクトの「静的検索可能」構成で、「supportUnmarshall」オプションを false に設定します。デフォルト値は true です。このオプションを設定すると、検索の一致はインデックスにマーシャリングされませんが、検索時間は非常に高速です。このオプションを false に設定すると、インデックスから非整列化されたオブジェクトが結果に含まれず、検索結果の一部として返された ID を使用してデータベースから一致するドメイン オブジェクトを取得する必要があるという欠点があります。これは悪いと思うかもしれませんが、そうではありません。この方法を使用すると、実際に検索結果が以前よりもはるかに速く表示されます。supportUnmarshall オプションの設定に関する情報の URL は、 http://grails.org/Searchable+Plugin+-+Mapping+-+Class+Mappingです。これは、「オプション」セクションの最後のオプションです。

2) Searchable.groovy 構成ファイルの defaultMethodOptions で「reload」を有効にします。したがって、次のようなものを Searchable.groovy ファイルに入れます。

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

この値を更新するには、Searchable Config プラグインを追加する必要があります。Searchable.groovy 構成ファイルの追加と編集の詳細については、Grail Searchable Plugin の Web ページを参照してください。私は十分な評判を持っていないので。2 つ以上のリンクを投稿することはできないため、Grails Searchable プラグインの Web ページに移動し、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]
}
于 2014-03-25T14:48:49.480 に答える