Grails的lucene搜索耗时太长



背景,我使用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域对象索引和我的域模型看起来像这样:我试图索引只有字段的名称和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]
    }
}

任何想法都将非常感激。这是我的一个自学项目,我很想用正确的方法来做搜索。:)谢谢,凯文

我在最近开发的一个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字节时,它将花费大量的时间。也许时间也与被编组对象的复杂性有关?不管怎样,我发现了一个和我有类似问题的人的博客文章。

http://webcache.googleusercontent.com/search?q=cache lebHKgX2yXUJ: blog.hououji.info/档案/165 +,cd = 10, hl = en& ct = clnk&美国gl =

总结这篇文章,当他搜索1000多个对象时,搜索时间大于15秒。就像我正在经历的一样。

他提到了两件事:

1)将"supportUnmarshall"选项设置为false,默认值为true,在域对象的"静态可搜索"配置中。通过设置此选项,搜索匹配不会被编组到索引中,但是搜索时间非常快。将此选项设置为false的缺点是,结果将不包含从索引中解编组的对象,并且必须使用作为搜索结果一部分返回的id从数据库中获取匹配的域对象。您可能会认为这很糟糕,但事实并非如此,使用这种方法,我的搜索结果实际上比以前显示得快得多。这里是关于设置supportUnmarshall选项的信息的URLhttp://grails.org/Searchable +插件+ - + + - +班级+映射的映射。它是"选项"部分的最后一个选项。

2)在Searchable的defaultMethodOptions中启用"reload"。Groovy配置文件。把这样的东西放到可搜索栏里。groovy文件:

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

你需要添加Searchable Config插件来更新这个值。添加和编辑Searchable的详细信息。groovy配置文件可以在Grail Searchable Plugin的网页上找到。因为我的名声不够高。我不能发布两个以上的链接,所以你需要去Grails Searchable插件的网页,并查找如何安装Searchable配置插件的文档。

给出一个性能改进的例子。以前,对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]
}

相关内容

  • 没有找到相关文章

最新更新