ElasticSearch學習29_基於Elasticsearch實現搜尋推薦
在基於Elasticsearch實現搜尋建議一文中我們曾經介紹過如何基於Elasticsearch來實現搜尋建議,而本文是在此基於上進一步優化搜尋體驗,在當搜尋無結果或結果過少時提供推薦搜尋詞給使用者。
背景介紹
在根據使用者輸入和篩選條件進行搜尋後,有時返回的是無結果或者結果很少的情況,為了提升使用者搜尋體驗,需要能夠給使用者推薦一些相關的搜尋詞,比如使用者搜尋【迪奧】時沒有找到相關的商品,可以推薦搜尋【香水】、【眼鏡】等關鍵詞。
設計思路
首先需要分析搜尋無結果或者結果過少可能的原因,我總結了一下,主要包括主要可能:
- 搜尋的關鍵詞在本網不存在,比如【迪奧】;
- 搜尋的關鍵詞在本網的商品很少,比如【科比】;
- 搜尋的關鍵詞拼寫有問題,比如把【阿迪達斯】寫成了【阿迪大斯】;
- 搜尋的關鍵詞過多,由於我們採用的是cross_fields,在一個商品內不可能包含所有的Term,導致無結果,比如【阿迪達斯 耐克 衛衣 運動鞋】;
那麼針對以上情況,可以採用以下方式進行處理:
- 搜尋的關鍵詞在本網不存在,可以通過爬蟲的方式獲取相關知識,然後根據搜尋建議詞去提取,比如去百度百科的迪奧詞條裡就能提取出【香水】、【香氛】和【眼鏡】等關鍵詞;當然基於爬蟲的知識可能存在偏差,此時需要能夠有人工稽核或人工更正的部分;
- 搜尋的關鍵詞在本網的商品很少,有兩種解決思路,一種是通過方式1的爬蟲去提取關鍵詞,另外一種是通過返回商品的資訊去聚合出關鍵詞,如品牌、品類、風格、標籤等,這裡我們採用的是後者(在測試後發現後者效果更佳);
- 搜尋的關鍵詞拼寫有問題,這就需要拼寫糾錯出場了,先糾錯然後根據糾錯後的詞去提供搜尋推薦;
- 搜尋的關鍵詞過多,有兩種解決思路,一種是識別關鍵詞的型別,如是品牌、品類、風格還是性別,然後通過一定的組合策略來實現搜尋推薦;另外一種則是根據使用者的輸入到搜尋建議詞裡去匹配,設定最小匹配為一個匹配到一個Term即可,這種方式實現比較簡單而且效果也不錯,所以我們採用的是後者。
所以,我們在實現搜尋推薦的核心是之前講到的搜尋建議詞,它提供了本網主要的關鍵詞,另外一個很重要的是它本身包含了關聯商品數的屬性,這樣就可以保證推薦給使用者的關鍵詞是可以搜尋出結果的。
實現細節
整體設計
整體設計框架如下圖所示:
搜尋推薦整體設計
搜尋建議詞索引
在基於Elasticsearch實現搜尋建議一文已有說明,請移步閱讀。此次增加了一個keyword.keyword_lowercase的欄位用於拼寫糾錯,這裡列取相關欄位的索引:
PUT /suggest_index
{
"mappings": {
"suggest": {
"properties": {
"keyword": {
"fields": {
"keyword": {
"type": "string",
"index": "not_analyzed"
},
"keyword_lowercase": {
"type": "string",
"analyzer": "lowercase_keyword"
},
"keyword_ik": {
"type": "string",
"analyzer": "ik_smart"
},
"keyword_pinyin": {
"type": "string",
"analyzer": "pinyin_analyzer"
},
"keyword_first_py": {
"type": "string",
"analyzer": "pinyin_first_letter_keyword_analyzer"
}
},
"type": "multi_field"
},
"type": {
"type": "long"
},
"weight": {
"type": "long"
},
"count": {
"type": "long"
}
}
}
}
}
商品資料索引
這裡只列取相關欄位的mapping:
PUT /product_index
{
"mappings": {
"product": {
"properties": {
"productSkn": {
"type": "long"
},
"productName": {
"type": "string",
"analyzer": "ik_smart"
},
"brandName": {
"type": "string",
"analyzer": "ik_smart"
},
"sortName": {
"type": "string",
"analyzer": "ik_smart"
},
"style": {
"type": "string",
"analyzer": "ik_smart"
}
}
}
}
}
關鍵詞對映索引
主要就是source和dest直接的對映關係。
PUT /conversion_index
{
"mappings": {
"conversion": {
"properties": {
"source": {
"type": "string",
"analyzer": "lowercase_keyword"
},
"dest": {
"type": "string",
"index": "not_analyzed"
}
}
}
}
}
爬蟲資料爬取
在實現的時候,我們主要是爬取了百度百科上面的詞條,在實際的實現中又分為了全量爬蟲和增加爬蟲。
全量爬蟲
全量爬蟲我這邊是從網上下載了一份他人彙總的詞條URL資源,裡面根據一級分類包含多個目錄,每個目錄又根據二級分類包含多個詞條,每一行的內容的格式如下:
李寧!http://baike.baidu.com/view/10670.html?fromTaglist
diesel!http://baike.baidu.com/view/394305.html?fromTaglist
ONLY!http://baike.baidu.com/view/92541.html?fromTaglist
lotto!http://baike.baidu.com/view/907709.html?fromTaglist
這樣在啟動的時候我們就可以使用多執行緒甚至分散式的方式爬蟲自己感興趣的詞條內容作為初始化資料保持到爬蟲資料表。為了保證冪等性,如果再次全量爬取時就需要排除掉資料庫裡已有的詞條。
增量爬蟲
- 在商品搜尋介面中,如果搜尋某個關鍵詞關聯的商品數為0或小於一定的閾值(如20條),就通過Redis的ZSet進行按天統計;
- 統計的時候是區分搜尋無結果和結果過少兩個Key的,因為兩種情況實際上是有所區別的,而且後續在搜尋推薦查詢時也有用到這個統計結果;
- 增量爬蟲是每天凌晨執行,根據前一天統計的關鍵詞進行爬取,爬取前需要排除掉已經爬過的關鍵詞和黑名單中的關鍵詞;
- 所謂黑名單的資料包含兩種:一種是每天增量爬蟲失敗的關鍵字(一般會重試幾次,確保失敗後加入黑名單),一種是人工維護的確定不需要爬蟲的關鍵詞;
爬蟲資料關鍵詞提取
- 首先需要明確關鍵詞的範圍,這裡我們採用的是suggest中型別為品牌、品類、風格、款式的詞作為關鍵詞;
- 關鍵詞提取的核心步驟就是對爬蟲內容和關鍵詞分別分詞,然後進行分詞匹配,看該爬蟲資料是否包含關鍵詞的所有Term(如果就是一個Term就直接判斷包含就好了);在處理的時候還可以對匹配到關鍵詞的次數進行排序,最終的結果就是一個key-value的對映,如{迪奧 -> [香水,香氛,時裝,眼鏡], 紀梵希 -> [香水,時裝,彩妝,配飾,禮服]};
管理關鍵詞對映
- 由於爬蟲資料提取的關鍵詞是和詞條的內容相關聯的,因此很有可能提取的關鍵詞效果不大好,因此就需要人工管理;
- 管理動作主要是包括新增、修改和置失效關鍵詞對映,然後增量地更新到conversion_index索引中;
搜尋推薦服務的實現
- 首先如果對搜尋推薦的入口進行判斷,一些非法的情況不進行推薦(比如關鍵詞太短或太長),另外由於搜尋推薦並非核心功能,可以增加一個全域性動態引數來控制是否進行搜尋推薦;
- 在設計思路裡面我們分析過可能有4中場景需要搜尋推薦,如何高效、快速地找到具體的場景從而減少不必要的查詢判斷是推薦服務實現的關鍵;這個在設計的時候就需要綜合權衡,我們通過一段時間的觀察後,目前採用的邏輯的虛擬碼如下:
public JSONObject recommend(SearchResult searchResult, String queryWord) {
try {
String keywordsToSearch = queryWord;
// 搜尋推薦分兩部分
// 1) 第一部分是最常見的情況,包括有結果、根據SKN搜尋、關鍵詞未出現在空結果Redis ZSet裡
if (containsProductInSearchResult(searchResult)) {
// 1.1) 搜尋有結果的 優先從搜尋結果聚合出品牌等關鍵詞進行查詢
String aggKeywords = aggKeywordsByProductList(searchResult);
keywordsToSearch = queryWord + " " + aggKeywords;
} else if (isQuerySkn(queryWord)) {
// 1.2) 如果是查詢SKN 沒有查詢到的 後續的邏輯也無法推薦 所以直接到ES裡去獲取關鍵詞
keywordsToSearch = aggKeywordsBySkns(queryWord);
if (StringUtils.isEmpty(keywordsToSearch)) {
return defaultSuggestRecommendation();
}
}
Double count = searchKeyWordService.getKeywordCount(RedisKeys.SEARCH_KEYWORDS_EMPTY, queryWord);
if (count == null || queryWord.length() >= 5) {
// 1.3) 如果該關鍵詞一次都沒有出現在空結果列表或者長度大於5 則該詞很有可能是可以搜尋出結果的
// 因此優先取suggest_index去搜索一把 減少後面的查詢動作
JSONObject recommendResult = recommendBySuggestIndex(queryWord, keywordsToSearch, false);
if (isNotEmptyResult(recommendResult)) {
return recommendResult;
}
}
// 2) 第二部分是通過Conversion和拼寫糾錯去獲取關鍵詞 由於很多品牌的拼寫可能比較相近 因此先走Conversion然後再拼寫檢查
String spellingCorrentWord = null, dest = null;
if (allowGetingDest(queryWord) && StringUtils.isNotEmpty((dest = getSuggestConversionDestBySource(queryWord)))) {
// 2.1) 爬蟲和自定義的Conversion處理
keywordsToSearch = dest;
} else if (allowSpellingCorrent(queryWord)
&& StringUtils.isNotEmpty((spellingCorrentWord = suggestService.getSpellingCorrectKeyword(queryWord)))) {
// 2.2) 執行拼寫檢查 由於在搜尋建議的時候會進行拼寫檢查 所以快取命中率高
keywordsToSearch = spellingCorrentWord;
} else {
// 2.3) 如果兩者都沒有 則直接返回
return defaultSuggestRecommendation();
}
JSONObject recommendResult = recommendBySuggestIndex(queryWord, keywordsToSearch, dest != null);
return isNotEmptyResult(recommendResult) ? recommendResult : defaultSuggestRecommendation();
} catch (Exception e) {
logger.error("[func=recommend][queryWord=" + queryWord + "]", e);
return defaultSuggestRecommendation();
}
}
其中涉及到的幾個函式簡單說明下:
- aggKeywordsByProductList方法用商品列表的結果,聚合出出現次數最多的幾個品牌和品類(比如各2個),這樣我們就可以得到4個關鍵詞,和原先使用者的輸入拼接後呼叫recommendBySuggestIndex獲取推薦詞;
- aggKeywordsBySkns方法是根據使用者輸入的SKN先到product_index索引獲取商品列表,然後再呼叫aggKeywordsByProductList去獲取品牌和品類的關鍵詞列表;
- getSuggestConversionDestBySource方法是查詢conversion_index索引去獲取關鍵詞提取的結果,這裡在呼叫recommendBySuggestIndex時有個引數,該引數主要是用於處理是否限制只能是輸入的關鍵詞;
- getSpellingCorrectKeyword方法為拼寫檢查,在呼叫suggest_index處理時有個地方需要注意一下,拼寫檢查是基於編輯距離的,大小寫不一致的情況會導致Elasticsearch Suggester無法得到正確的拼寫建議,因此在處理時需要兩邊都轉換為小寫後進行拼寫檢查;
- 最終都需要呼叫recommendBySuggestIndex方法獲取搜尋推薦,因為通過suggest_index索引可以確保推薦出去的詞是有意義的且關聯到商品的。該方法核心邏輯的虛擬碼如下:
private JSONObject recommendBySuggestIndex(String srcQueryWord, String keywordsToSearch, boolean isLimitKeywords) {
// 1) 先對keywordsToSearch進行分詞
List<String> terms = null;
if (isLimitKeywords) {
terms = Arrays.stream(keywordsToSearch.split(",")).filter(term -> term != null && term.length() > 1)
.distinct().collect(Collectors.toList());
} else {
terms = searchAnalyzeService.getAnalyzeTerms(keywordsToSearch, "ik_smart");
}
if (CollectionUtils.isEmpty(terms)) {
return new JSONObject();
}
// 2) 根據terms搜尋構造搜尋請求
SearchParam searchParam = new SearchParam();
searchParam.setPage(1);
searchParam.setSize(3);
// 2.1) 構建FunctionScoreQueryBuilder
QueryBuilder queryBuilder = isLimitKeywords ? buildQueryBuilderByLimit(terms)
: buildQueryBuilder(keywordsToSearch, terms);
searchParam.setQuery(queryBuilder);
// 2.2) 設定過濾條件
BoolQueryBuilder boolFilter = QueryBuilders.boolQuery();
boolFilter.must(QueryBuilders.rangeQuery("count").gte(20));
boolFilter.mustNot(QueryBuilders.termQuery("keyword.keyword_lowercase", srcQueryWord.toLowerCase()));
if (isLimitKeywords) {
boolFilter.must(QueryBuilders.termsQuery("keyword.keyword_lowercase", terms.stream()
.map(String::toLowerCase).collect(Collectors.toList())));
}
searchParam.setFiter(boolFilter);
// 2.3) 按照得分、權重、數量的規則降序排序
List<SortBuilder> sortBuilders = new ArrayList<>(3);
sortBuilders.add(SortBuilders.fieldSort("_score").order(SortOrder.DESC));
sortBuilders.add(SortBuilders.fieldSort("weight").order(SortOrder.DESC));
sortBuilders.add(SortBuilders.fieldSort("count").order(SortOrder.DESC));
searchParam.setSortBuilders(sortBuilders);
// 4) 先從快取中獲取
final String indexName = SearchConstants.INDEX_NAME_SUGGEST;
JSONObject suggestResult = searchCacheService.getJSONObjectFromCache(indexName, searchParam);
if (suggestResult != null) {
return suggestResult;
}
// 5) 呼叫ES執行搜尋
SearchResult searchResult = searchCommonService.doSearch(indexName, searchParam);
// 6) 構建結果加入快取
suggestResult = new JSONObject();
List<String> resultTerms = searchResult.getResultList().stream()
.map(map -> (String) map.get("keyword")).collect(Collectors.toList());
suggestResult.put("search_recommendation", resultTerms);
searchCacheService.addJSONObjectToCache(indexName, searchParam, suggestResult);
return suggestResult;
}
private QueryBuilder buildQueryBuilderByLimit(List<String> terms) {
FunctionScoreQueryBuilder functionScoreQueryBuilder
= new FunctionScoreQueryBuilder(QueryBuilders.matchAllQuery());
// 給品類型別的關鍵詞加分
functionScoreQueryBuilder.add(QueryBuilders.termQuery("type", Integer.valueOf(2)),
ScoreFunctionBuilders.weightFactorFunction(3));
// 按詞出現的順序加分
for (int i = 0; i < terms.size(); i++) {
functionScoreQueryBuilder.add(QueryBuilders.termQuery("keyword.keyword_lowercase",
terms.get(i).toLowerCase()),
ScoreFunctionBuilders.weightFactorFunction(terms.size() - i));
}
functionScoreQueryBuilder.boostMode(CombineFunction.SUM);
return functionScoreQueryBuilder;
}
private QueryBuilder buildQueryBuilder(String keywordsToSearch, Set<String> termSet) {
// 1) 對於suggest的multi-fields至少要有一個欄位匹配到 匹配得分為常量1
MultiMatchQueryBuilder queryBuilder = QueryBuilders.multiMatchQuery(keywordsToSearch.toLowerCase(),
"keyword.keyword_ik", "keyword.keyword_pinyin",
"keyword.keyword_first_py", "keyword.keyword_lowercase")
.analyzer("ik_smart")
.type(MultiMatchQueryBuilder.Type.BEST_FIELDS)
.operator(MatchQueryBuilder.Operator.OR)
.minimumShouldMatch("1");
FunctionScoreQueryBuilder functionScoreQueryBuilder
= new FunctionScoreQueryBuilder(QueryBuilders.constantScoreQuery(queryBuilder));
for (String term : termSet) {
// 2) 對於完全匹配Term的加1分
functionScoreQueryBuilder.add(QueryBuilders.termQuery("keyword.keyword_lowercase", term.toLowerCase()),
ScoreFunctionBuilders.weightFactorFunction(1));
// 3) 對於匹配到一個Term的加2分
functionScoreQueryBuilder.add(QueryBuilders.termQuery("keyword.keyword_ik", term),
ScoreFunctionBuilders.weightFactorFunction(2));
}
functionScoreQueryBuilder.boostMode(CombineFunction.SUM);
return functionScoreQueryBuilder;
}
最後,從實際執行的統計來看,有90%以上的查詢都能在1.3)的情況下返回推薦詞,而這一部分還沒有進行拼寫糾錯和conversion_index索引的查詢,因此還是比較高效的;剩下的10%在最壞的情況且快取都沒有命中的情況下,最多還需要進行三次ES的查詢,效能是比較差的,但是由於有快取而且大部分的無結果的關鍵詞都比較集中,因此也在可接受的範圍,這一塊可以考慮再增加一個動態引數,在大促的時候進行關閉處理。
小結與後續改進
- 通過以上的設計和實現,我們實現了一個效果不錯的搜尋推薦功能,線上使用效果如下:
//搜尋【迪奧】,本站無該品牌商品
沒有找到 "迪奧" 相關的商品, 為您推薦 "香水" 的搜尋結果。或者試試 "香氛" "眼鏡"
//搜尋【puma 運動鞋 上衣】,關鍵詞太多無法匹配
沒有找到 "puma 運動鞋 上衣" 相關的商品, 為您推薦 "PUMA 運動鞋" 的搜尋結果。或者試試 "PUMA 運動鞋 女" "PUMA 運動鞋 男"
//搜尋【puma 上衣】,結果太少
"puma 上衣" 搜尋結果太少了,試試 "上衣" "PUMA" "PUMA 休閒" 關鍵詞搜尋
//搜尋【51489312】特定的SKN,結果太少
"51489312" 搜尋結果太少了,試試 "夾克" "PUMA" "戶外" 關鍵詞搜尋
//搜尋【blackjauk】,拼寫錯誤
沒有找到 "blackjauk" 相關的商品, 為您推薦 "BLACKJACK" 的搜尋結果。或者試試 "BLACKJACK T恤" "BLACKJACK 休閒褲"
- 後續考慮的改進包括:1.繼續統計各種無結果或結果太少場景出現的頻率和對應推薦詞的實現,優化搜尋推薦服務的效率;2.爬取更多的語料資源,提升conversion的能力;3.考慮增加個性化的功能,給使用者推薦Ta最感興趣的內容。
原文來自:http://www.jianshu.com/p/4ab3c69e7b19
原博主連結:http://www.jianshu.com/u/0ffaa3601861
相關推薦
ElasticSearch學習29_基於Elasticsearch實現搜尋推薦
在基於Elasticsearch實現搜尋建議一文中我們曾經介紹過如何基於Elasticsearch來實現搜尋建議,而本文是在此基於上進一步優化搜尋體驗,在當搜尋無結果或結果過少時提供推薦搜尋詞給使用者。 背景介紹 在根據使用者輸入和篩選條件進行搜尋後,有時返回的是無
elasticsearch(11)通過ngram分詞機制實現搜尋推薦
轉載自簡書本文連結地址: Elasticsearch通過ngram分詞機制實現搜尋推薦 1、什麼是ngram 例如英語單詞 quick,5種長度下的ngram ngram length=1,q u i c k ngram length=2,qu ui ic ck ngram le
【深度學習】基於Numpy實現的神經網路進行手寫數字識別
直接先用前面設定的網路進行識別,即進行推理的過程,而先忽視學習的過程。 推理的過程其實就是前向傳播的過程。 深度學習也是分成兩步:學習 + 推理。學習就是訓練模型,更新引數;推理就是用學習到的引數來處理新的資料。 from keras.datasets.mnist impor
Android開發學習之基於ZBar實現微信掃一掃
蟄伏半月有餘,一直在準備期末考試,期間抽空研究了一些Android的原始碼,現在我就把在這其中的一些收穫分享給大家。 今天想分享給大家的是二維碼掃描。說起二維碼,大家一定不會陌生,尤其是微信火了以後,在我們的生活中幾乎隨處都可以看到二維碼的
elasticsearch使用More like this實現基於內容的推薦
無限 itl percent 結果 忽略 class terms query col 基於內容的推薦通常是給定一篇文檔信息,然後給用戶推薦與該文檔相識的文檔。Lucene的api中有實現查詢文章相似度的接口,叫MoreLikeThis。Elasticsearch封裝了該接口
elasticsearch學習之通過設定搜尋邊界實現精確匹配欄位
GET tmdb/_search { "_source": "name_exact_match", "query": { "bool": { "should": [ { "constant_sco
基於Elasticsearch實現搜尋建議
搜尋建議是搜尋的一個重要組成部分,一個搜尋建議的實現通常需要考慮建議詞的來源、匹配、排序、聚合、關聯的文件數和拼寫糾錯等,本文介紹一個基於Elasticsearch實現的搜尋建議。 問題描述 電商網站的搜尋是最基礎最重要的功能之一,搜尋框上面的良好體驗能
ElasticSearch學習筆記(九)Java AP實現搜尋,排序,高亮,分頁
雖然上一篇中的對索引的搜尋可以在一定程度上獲取索引的資訊,但是畢竟功能是有限的,本篇主要是對elasticsearch使用javaAPI實現搜尋功能的筆記。 一、搜尋 package test; import static org.elastics
Elasticsearch 學習之攜程機票ElasticSearch集群運維馴服記(強烈推薦)
使用情況 strong 簡單 而且 第一個 並不是 5.x ber als 轉自: https://mp.weixin.qq.com/s/wmSTyIGCVhItVNPHcH7nsA 一、整體架構 為什麽采用ES作為搜索引擎呢?在做任何事情的時候,不要一上來就急
Elasticsearch學習之深入搜尋一 --- 提高查詢的精準度
為帖子增加標題欄位 POST /forum/article/_bulk { "update": { "_id": "1"} } { "doc" : {"title" : "this is java and elasticsearch blog"} } { "update":
搜尋推薦一——Centos搭建Elasticsearch單機實戰
環境 jdk: 1.8 centos: 7 elasticsearch: 5.3.0 一、JDK安裝 $: tar -zxvf jdk-8u181-linux-x64.tar.gz $: mkdir /usr/local/java $: cp jdk1.8
2018基於ElasticSearch的找房網實戰開發企業級房屋搜尋網
當前網際網路行業,資料檢索、資料分析等大資料相關的產品異常火爆,而ElasticSearch是當下最火的分散式搜尋引擎及大資料分析中介軟體 ,瞭解並掌握ElasticSearch的實用場景及相關技能 ,必將提升你在網際網路行業的核心競爭力,讓你可以輕鬆走進BAT 業務- 分角
【備忘】全網最新基於ElasticSearch的找房網實戰開發企業級房屋搜尋網視訊教程
當前網際網路行業,資料檢索、資料分析等大資料相關的產品異常火爆,而ElasticSearch是當下最火的分散式搜尋引擎及大資料分析中介軟體 ,瞭解並掌握ElasticSearch的實用場景及相關技能 ,必將提升你在網際網路行業的核心競爭力,讓你可以輕鬆走進BAT 業務-分角
ElasticSearch基於Java實現員工資訊的增刪改查
員工資訊 姓名 年齡 職位 國家 入職日期 薪水 1、maven依賴 org.elasticsearch.client transport 5.2.2 org.apache.logging.log4j log4j-api 2.7 org.apache.logging.log4j lo
基於ElasticSearch實現商品的全文檢索檢索
全文檢索相關概念 資料分類; 結構化資料:行資料,儲存在資料庫裡,可以用二維表結構來邏輯表達實現的資料能夠用資料或統一的結構加以表示,可以用數字和符號加以表示 非結構化資料:無法用數字或統一的結構表示 文字、影象、聲音、網頁
Python基於Elasticsearch實現搜尋引擎
&nbsp; &NBSP; &NBSP; &NBSP; ElasticSearch是一個基於Lucene的搜尋伺服器。它提供了一個分散式多使用者能力的全文搜尋引擎,基於RESTful Web介面.Elasticsearch是用Java開發的,並作為Apac
elasticsearch實現搜尋拼音然後高亮內容
es拼音外掛https://github.com/medcl/elasticsearch-analysis-pinyin/tree/v1.6.0,具體用法此處不介紹,看readme 現在要實現一個搜場館的功能,需要按場館名稱首字母縮寫也能搜尋出場館,還必須要高亮顯示首拼對
企業級搜尋系統案例原始碼(已經非常精簡),根據現公司專案搭建,基於 elasticsearch + canal,可支援千萬量級以上實時搜尋。
一、準備工作: IDEA: 略 JDK1.8: 略 mysql資料庫: 略 安裝完mysql資料庫後,把bin_log設定開啟,如果不確定是否已經開啟,可執行 show variables like ‘log_bin%’; 如果顯示如下,那說明
Elasticsearch 基於 URL 的搜尋請求
背景 Elasticsearch 不像關係型資料庫,沒有簡易的 SQL 用來查詢資料,只能通過呼叫 RESTful API 實現查詢。大體上查詢分為兩種,基於 URL 的和基於請求主體的。基於 URL 的方式比較簡單清晰,用得較多,在這簡單記錄下。 基本模式 基於 URL 的搜尋請求
Elasticsearch 之(21)字首搜尋、萬用字元搜尋、正則搜尋、推薦搜尋 和 模糊搜尋
1、字首搜尋搜尋包含KDKE字首的articleID GET /forum/article/_search { "query": { "prefix": { "articleID": { "value": "KDKE" }