成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

使用 Redis 實現(xiàn)自動補全功能

or0fun / 1115人閱讀

摘要:自動補全也可以稱為自動提示,類似于在百度搜索的輸入框中輸入一個字符,下面會提示多個關(guān)鍵詞供參考。使用倒是一個很不錯的方案。雖然通過的通配符方式也可以實現(xiàn)自動提示,但是這種方法在中數(shù)據(jù)量較大時也存在性能問題。

自動補全也可以稱為自動提示,類似于在百度搜索的輸入框中輸入一個字符,下面會提示多個關(guān)鍵詞供參考。

假設(shè):

輸入 a,會自動提示 apple、application、acfun、adobe;
輸入 ap,提示 apple、application;
輸入 ac,提示 acfun;
輸入 ad,提示 adobe。

看到這個功能需求,很簡單的方式就是在數(shù)據(jù)庫中直接使用 SQL LIKE 操作符來匹配,但是性能肯定是不行的。使用 Redis 倒是一個很不錯的方案。

Redis 是 KV 型數(shù)據(jù)庫,查詢都是基于 key 的,key 值必須具有唯一性。

雖然通過 key 的通配符方式也可以實現(xiàn)自動提示,但是這種方法在 Redis 中數(shù)據(jù)量較大時也存在性能問題。

回到上面的話題,本質(zhì)就是我希望通過 a 獲取 apple、application、acfun、adobe,通過 ap 獲取 apple、application,以此類推。那么,需要查詢的值就應(yīng)該作為 key,查詢結(jié)果應(yīng)該作為 value。遵循這個思路,可以利用 Redis 的集合存儲這些值。為什么不用列表,而使用集合?因為我希望查詢出來的詞不會重復(fù),而集合的特性就是元素唯一,性質(zhì)決定用途,所以就使用集合。一般情況下,查詢出來的詞也會按照熱度頻率什么的排序,需要排序的話,就要使用 Redis 的有序集合。

以 word: 為前綴,方便管理和區(qū)別(保證唯一性),后面跟上要查詢的值,例如:word:a(其實這樣還是無法確保唯一性,就假設(shè)這個 key 在 Redis 中是唯一的)。
向集合中添加 關(guān)鍵詞:

bashZADD word:a 0 apple 0 application 0 acfun 0 adobe
ZADD word:ap 0 apple 0 application
ZADD word:app 0 apple 0 application
ZADD word:appl 0 apple 0 application
ZADD word:apple 0 apple
ZADD word:appli 0 application
……

上面還沒有添加完成,完整添加的代碼如下:

phpredis = $redis;
    }


    public function add($word) {
        $len = mb_strlen($word, "UTF-8");
        for ($i = 1; $i <= $len; $i++) {
            $sub = mb_substr($word, 0, $i, "UTF-8");
            $this->redis->zAdd(self::PREFIX . $sub, 0, $word);
        }
    }

}

看以上代碼,應(yīng)該發(fā)現(xiàn)我給有序集合每個元素的 score 為 0,這個意義何在?不應(yīng)該給每個詞不同的 score,以便給搜索結(jié)果排序嗎?確實如此,但是這樣會存在一個問題:某一個詞會出現(xiàn)在多個集合中,如果該詞的熱點要增加,那么就需要同時更新多個集合中該詞的 score。這顯然是不合理的。

那么到底應(yīng)該怎么辦哩?再創(chuàng)建一個有序集合,專門用于存放這些詞和它們的 score。最后,將查詢結(jié)合和這個記錄熱度的集合做交集,就能得出按熱度排列后的結(jié)果。

設(shè)置這些詞的熱度:

bashZADD word_scores 100 apple 80 adobe 70 application 60 acfun

交集:

bashZINTERSTORE word_result 2 word_scores word:a WEIGHTS 1 1
ZRANGE word_result 0 -1 withscores

具體 PHP 實現(xiàn)代碼如下,僅供參考:

phpredis = $redis;
    }


    public function add($word) {
        $len = mb_strlen($word, "UTF-8");
        for ($i = 1; $i <= $len; $i++) {
            $sub = mb_substr($word, 0, $i, "UTF-8");
            $this->redis->zAdd(self::PREFIX . $sub, 0, $word);
        }
    }


    public function incScore($word, $score = 1) {
        return $this->redis->zIncrBy(self::WORDS_PREFIX, $score, $word);
    }


    public function search($keyword, $stop = 5) {
        $this->redis->zInter(self::RESULT_PREFIX, array(self::PREFIX . $keyword, self::WORDS_PREFIX), array(1, 1));
        return $this->redis->zRevRange(self::RESULT_PREFIX, 0, $stop, true);
    }

}

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/30241.html

相關(guān)文章

  • 使用php+phantomjs構(gòu)建一只簡單爬蟲的開發(fā)思路

    摘要:嘮叨最近頻繁的給客戶做采集功能既然代碼無法公布所以一直想寫個思路類的文章既然是簡單的爬蟲那么一切自然以簡單為原則能少用的都少用比如和這兩個神兵利器就被我省略了打造這只蟲子就像是樵夫砍柴一般該磨刀還是要磨刀遠(yuǎn)觀拜拜山頭對象站點國內(nèi)知名電商平臺 嘮叨: 最近頻繁的給客戶做采集功能,既然代碼無法公布,所以一直想寫個思路類的文章.既然是簡單的爬蟲,那么一切自然以簡單為原則,能少用的都少用,比如...

    liangdas 評論0 收藏0
  • java | Spring Boot 與 Redis 實現(xiàn) Cache 以及 Session 共享

    摘要:完成狀態(tài)編寫中已完成維護中原文是一個使用編寫的開源支持網(wǎng)絡(luò)基于內(nèi)存可選持久性的鍵值對存儲數(shù)據(jù)庫維基百科是目前業(yè)界使用廣泛的基于內(nèi)存的數(shù)據(jù)庫。 完成狀態(tài) [ ] 編寫中 [ ] 已完成 [x] 維護中 原文 Redis Redis是一個使用ANSI C編寫的開源、支持網(wǎng)絡(luò)、基于內(nèi)存、可選持久性的鍵值對存儲數(shù)據(jù)庫 ------ 維基百科 Redis 是目前業(yè)界使用廣泛的基于內(nèi)存的...

    ssshooter 評論0 收藏0

發(fā)表評論

0條評論

or0fun

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<