對于一個網(wǎng)站來說,無論是商城網(wǎng)站還是門戶網(wǎng)站,搜索框都是有一個比較重要的地位,它的存在可以說是為了讓用戶更快、更方便的去找到自己想要的東西。對于經(jīng)常逛這個網(wǎng)站的用戶,當然也會想知道在這里比較“火”的東西是什么,這個時候我們搜索框上的熱詞就起作用了。其實我覺得這一塊的完善會對這個網(wǎng)站帶來許多益處。
可能現(xiàn)在比較普遍的做法是把這些相應的信息存到我們的關系型數(shù)據(jù)庫中,如sql server 和 oracle。方便起見的話,可能每搜索一次就往表里插一次數(shù)據(jù),用的時候要先統(tǒng)計數(shù)據(jù),統(tǒng)計完后再排序,最后才展示。這種情況下,如果搜索量很大的話,表的膨脹速度就會非常快,如果sql沒寫好,查詢的時候估計會。。相比Redis,同等條件下,Redis的速率肯定是會較優(yōu),畢竟是從內(nèi)存中拿出來的。
下面我們就用.NET Core和StackExchange.Redis來做一下這個簡單的案例。
案例用到的一些相關技術(shù)和說明:
開始正題之前,我們要確定用Redis中的那種數(shù)據(jù)結(jié)構(gòu),五種之中比較合適的應該是SortedSet,我們可以用成員來作為搜索詞,成員分數(shù)來作為搜索詞的搜索次數(shù),這樣就可以很方便的來操作相關的數(shù)據(jù)了。
下面開始正題:
我們在開始的時候需要初始化一下數(shù)據(jù)。這里就直接在第一次運行的時候初始化。用上流水線的技術(shù),速度還是很可觀的。初始化了70個搜索關鍵詞(NBA球星),然后用隨機數(shù)作為關鍵字的下標,去隨機給這個關鍵字加1分。這個分數(shù)就是這個關鍵字被搜索的次數(shù)。下面來看看初始化的相關代碼:
publicIActionResultIndex(){//keysIList
這里是在加載這個頁面的時候就把這些熱搜詞存進Redis中,這樣我們才能有數(shù)據(jù)來演示啊。這里還用到了一個非事務型的流水線。就是把要操作的指令存放到一個隊列中,最后把這個隊列扔到服務端去執(zhí)行,這樣就有效的減少了不必要的網(wǎng)絡傳輸,同時也提高了執(zhí)行速度。
好了,初始數(shù)據(jù)有了,下面要做的就是用戶在搜索的時候,根據(jù)用戶的輸入去匹配搜索次數(shù)多的關鍵字,展示最Hot的10個,當然這個展示的個數(shù)是隨我們定的,最后可以考慮把這個放到我們的配置文件中去,甚至是放到數(shù)據(jù)庫中,
為的是靈活和方便維護。下面是我們在后臺的處理邏輯:
publicIActionResultGetHotKey(stringkey=""){if(string.IsNullOrEmpty(key)){//defaultvarres=_redis.ZRevRange(_searchKey,0,9);varlist=(fromiinresselecti.ToString());returnJson(list);}else{//byuserinputvarres=_redis.ZRevRange(_searchKey,0,-1);varlist=(fromiinresselecti.ToString()).Where(x=>x.Contains(key)).Take(10).ToList();returnJson(list);}}
對于查詢的處理是非常的簡單的,用戶不小心輸入空格的時候就展示最熱的10個關鍵詞,如果用戶有輸入的話,就把關鍵詞中包含用戶輸入的展示出來。那么我們在頁面上要做些什么呢?下面就是我們演示用的搜索框。
相應的js是寫到 scripts 這個section中的,js的話是比較簡單的就是用ajax去請求我們要展示的數(shù)據(jù)。更多的應該是jquery-ui的api問題,大家也可以換用自己比較熟悉的組件,舉一反三即可。下面是autocomplete的api,如果有需要可以去看一下。
@sectionscripts{}
到這里,用戶搜索前的操作,我們是做好了,下面先來看一下效果。
那么用戶點擊了搜索之后我們要做些什么處理呢?無論是新的關鍵字還是已有的關鍵字,我們都是要做處理的,當然redis中zincrby命令來處理這個是十分合適的,存在的就把分數(shù)加1,不存在就創(chuàng)建一個分數(shù)為1的成員。下面是搜索時的后臺邏輯處理:
[HttpPost]publicIActionResultSetHotKey(stringkey){if(!string.IsNullOrWhiteSpace(key)){_redis.ZIncrby(_searchKey,key);//other//...returnJson(new{code="000",msg="OK"});}else{returnJson(new{code="999",msg="keywordcannotbeempty!"});}}
限制了用戶不能搜索空關鍵字,在把這個關鍵字存儲或者分數(shù)加一之后,就是展示我們的搜索的結(jié)果。這個搜索的結(jié)果一般是從solr等全文檢索的地方查出來的,不是我們講的重點,所以就忽略了。然后我們還要加一段js去處理我們搜索的時候應該做的操作。當然,都是些比較簡單的操作。
//search$("#searchSubmit").click(function(){$.ajax({url:"@Url.Action("SetHotKey","Auto")",dataType:"json",type:"POST",data:{key:$("#key").val()},success:function(data){if(data.code=="000"){$("
searchsuccessful!
").appendTo("#result");}else{$(""+data.msg+"
").appendTo("#result");}}});});下面是效果圖:
在演示的時候,我們搜索了“我愛你”和“我不信”,在Redis的客戶端我們找出搜索次數(shù)最少的6個,然后就可以看到我們那兩個關鍵字最的分數(shù)都是1。確定是剛插入的數(shù)據(jù)。
到這里,我們做的這個熱搜詞可以說是大功告成了。當然這可以說是最最最簡單的一個雛形。我們還可以適當?shù)奶砑右恍〇|西讓這個功能變得更加完善。比如我可以在搜索展示的時候顯示一下搜索的次數(shù)等。
最后是完整的控制器和頁面代碼:
usingAutoCompleteDemo.Common;usingMicrosoft.AspNetCore.Mvc;usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;namespaceAutoCompleteDemo.Controllers{publicclassAutoController:Controller{privatereadonlyIRedis_redis;privatereadonlystring_searchKey="search";publicAutoController(IRedisredis){_redis=redis;}publicIActionResultIndex(){//keysIList
-
數(shù)據(jù)結(jié)構(gòu)
關注
3文章
573瀏覽量
40124 -
Redis
+關注
關注
0文章
374瀏覽量
10871
原文標題:Redis 簡單案例(一):網(wǎng)站搜索的熱搜詞
文章出處:【微信號:DBDevs,微信公眾號:數(shù)據(jù)分析與開發(fā)】歡迎添加關注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關推薦
評論