繁体   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