1

我已经使用 jQuery 自动完成实现了一个基本的自动完成功能。我每次都在查询数据库,这使得自动完成的事情变得很慢。我正在寻找使它更快的方法,就像 Quora 一样。

这是来自前端的代码:

<script type="text/javascript">


var URL2 = '<?php e(SITE_URL); ?>fronts/searchKeywords';

jQuery(document).ready(function(){

var CityKeyword = jQuery('#CityKeyword');

CityKeyword.autocomplete({
minLength    : 1,
source        : URL2
});

});
 </script>

这是来自服务器端的代码:

function searchKeywords(){

    if ($this->RequestHandler->isAjax() ) {
        $this->loadModel('Expertise_area');
        Configure::write ( 'debug',0);
        $this->autoRender=false;

        $expertise=$this->Expertise_area->find('all',array(
                'conditions'=>array('Expertise_area.autocomplete_text LIKE'=>'%'.$_GET['term'].'%'), 
                'fields' => array('DISTINCT (Expertise_area.autocomplete_text) AS autocomplete_text'),
                'limit'=>5
        ));
        $i=0;
        if(!empty($expertise)){
            $len = strlen($_GET['term']);
            foreach($expertise as $valueproductname){
                $pos = stripos($valueproductname['Expertise_area']['autocomplete_text'],$_GET['term']);
                $keyvalue = "";

                if($pos == 0) {
                    $keyvalue= "<strong>".substr($valueproductname['Expertise_area']['autocomplete_text'],$pos,$len)."</strong>"
                            .substr($valueproductname['Expertise_area']['autocomplete_text'],$len);
                }else {
                    $keyvalue= substr($valueproductname['Expertise_area']['autocomplete_text'],0,$pos)."<strong>"
                            .substr($valueproductname['Expertise_area']['autocomplete_text'],$pos,$len)."</strong>"
                            .substr($valueproductname['Expertise_area']['autocomplete_text'],$pos+$len);
                }


                $response[$i]['value']=$valueproductname['Expertise_area']['autocomplete_text'];
                $response[$i]['label']="<span class=\"username\">".$keyvalue."</span>";
                $i++;

            }
            echo json_encode($response);
        }else{
        }
}
}

我进行了一些研究,到目前为止,以下解决方案值得一看:

  1. 在页面加载时查询数据并将其存储在 COOKIE 中以备将来使用。

  2. 实现一些缓存机制(memcache??)。但是我的网站在 Cakephp 上,如果我是对的,它会在内部进行 cahcing。因此,是否值得朝这个方向发展。

  3. 使用一些第三方索引机制,如 Solr、Lucene 等。对此了解不多。

  4. 自己实现一个非常复杂的“前缀搜索”

正确的方法是什么?请帮帮我。

4

2 回答 2

1

我正在为我的问题添加一个解决方案,这是我经过大量研究后发现的。

问题是:

  1. 每次用户更改搜索框中的文本时,我都使用 Ajax 从数据库中获取关键字

  2. 我正在进行通配符搜索以匹配整个字符串中的搜索项,而不仅仅是 ex 关键字的开头。“dev”将返回“社会发展”、“发展”等

解决方案:

  1. 我有一个固定的关键字数组(200 个),在不久的将来不会成倍增长。因此,我目前没有进行复杂的索引,而是将所有关键字发送到一个数组中。

  2. 我在页面加载时以数组的形式发送这些数据,因为它很小。如果它变大,我将通过不同索引数组中的一些 ajax 在后台获取它。

  3. 我正在使用 jQuery 的自动完成小部件为我完成剩下的事情。

  4. 为了突出显示搜索项,我通过解决 __renderItem 来使用 hack。(从 Stackoverflow 复制。谢谢!!)

代码:

function monkeyPatchAutocomplete() { //Hack to color search item

jQuery.ui.autocomplete.prototype._renderItem = function( ul, item) {
    var re = new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + this.term + ")(?![^<>]*>)(?![^&;]+;)", "gi");
    var t = item.label.replace(re,"<span style='font-weight:bold;color:#434343;'>" + 
            "$&" + 
            "</span>");
    return jQuery( "<li></li>" )
        .data( "item.autocomplete", item )
        .append( "<a>" + t + "</a>" )
        .appendTo( ul );
};
}

function getKeywords(){ 
//Function that returns list of keywords. I am using an array since my data is small.
//This function can be modified to fetch data in whatever way one want. 
//I intend to use indexed arrays in future if my data becomes large.

    var allKeywords = <?php echo json_encode($allKeywords); ?>;

    return allKeywords;
}

jQuery(document).ready(function(){

monkeyPatchAutocomplete();

var CityKeyword = jQuery('#CityKeyword');

CityKeyword.autocomplete({
minLength    : 1,
source        : getKeywords()
});

});
于 2013-08-16T06:32:38.477 回答
1

我从来没有试过这个,但很快就会为我正在做的一个项目做这个。

我总是考虑在初始页面加载期间收到一些 AJAX(或者可能只是将其包含在页面中)每个字母的前 10 个单词的可能性.. 例如

A - apples, anoraks, alaska, angela, aha, air, arrgh, any, alpha, america B - 黄油, bob 等等......

这样,当用户按下 AZ 时,您可以立即为他们提供 10 个最受欢迎的关键字,而无需任何进一步的请求,因为您已经将它们存储在 JS 中的数组中。

我不确定大小/内存使用情况,但这可以进一步扩展以处理前 2 个字母,例如 AA、AB、AC.....BA、BB、BC.... ZA、ZB、ZZ.. ..当然很多组合比如ZZ开头的单词是没有数据的,除非是音乐网站,而且是ZZ Top!这意味着在初始页面加载期间发送此数据可能不会占用太多内存或带宽。只有当用户键入第三个字母时,您才需要进行任何进一步的数据查找/传输。

您可以每天、每周或其他任何时间自动更新此数据,具体取决于站点使用情况和最流行的搜索。

于 2013-08-15T05:48:40.597 回答