用Elasticsearch構建電商搜索平臺

電商數據系統主要類型

一箇中等的電商平臺,天天都要產生百萬條原始數據,上億條用戶行爲數據。通常來講,電商數據通常有3種主要類型的數據系統:node

  1. 關係型數據庫 ,大多數互聯網公司會選用mysql做爲關數據庫的主選,用於存儲商品,用戶信息等數據。 關係型數據庫對於事務性很是高的OLTP操做(好比訂單,結算等)支持良好。
  2. hadoop生態 ,hadoop是數據倉庫主要的載體,除了備份關係型數據庫的全部版本,還存儲用戶行爲,點擊,曝光,互動等海量日誌數據,hadoop對於數據分析,數據挖掘等OLAP支持比關係型數據庫更加具備擴展性和穩定性。
  3. 搜索引擎 ,以elasticsearch和solr爲表明。搜索引擎是獲取信息最高效的途徑,幾乎成爲各種網站,應用的基礎標配設施(地位僅次於數據庫)。

目前搜索引擎技術已經有很是成熟的開源解決方案,最出名的ElasticSearch和Solr都是基於lucence的。不少中小型互聯網公司搜索引擎都是基於這兩個開源系統搭建的,可是即使如此,一個搜索引擎團隊想把搜索引擎質量作到商用標準,從系統熟悉,服務搭建,功能定製,一般須要花費較長時間。mysql

通用搜索引擎應用在互聯網商用搜索 一般會遇到以下幾個問題 :算法

  • 搜索引擎與公司現有數據系統的集成。mysql 和 hadoop是電商的兩個主要數據載體,搜索引擎在全量和增量建索引過程當中必須和mysql或hadoop無縫集成,才能發揮搜索引擎自身的實時性,水平擴展性(性能與容量和機器數量成正比)等優點。
  • 商用搜索高度定製化與通用搜索引擎的矛盾。商用搜索的問題有時候超越了搜索引擎自己解決的範圍,好比商品的去重,店鋪的去重須要很專業的搜索引擎使用技巧; 商品的權重,用戶意圖的識別須要算法和模型的支持。
  • 在不瞭解搜索引擎專業知識的前提下,很難建立對性能友好的索引。結果形成了通用搜索性能不好的假象。

筆者是有贊大數據架構師,從自身的搜索實踐出發,分享搜索引擎實際的架構和解決的問題。sql

搜索引擎架構

有贊搜索引擎實踐,上半部分主要介紹搜索引擎的架構和性能優化方面的經驗;下半部分是算法篇,介紹有贊實際須要的搜索算法的問題和解決方案。文章僅僅介紹一箇中型電商公司實際的使用現狀和筆者我的的經驗,不表明搜索引擎最佳實踐方法,也不表明能夠適用全部的場景。數據庫

1.技術架構

有贊搜索引擎基於分佈式實時引擎elasticsearch(ES)。ES構建在開源社區最穩定成熟的索引庫lucence上,支持多用戶租用,高可用,可水平擴展;並有自動容錯和自動伸縮的機制。咱們同事還實現了es與mysql和hadoop的無縫集成;咱們自主開發了高級搜索模塊提供靈活的相關性計算框架等功能。編程

2.索引構建

互聯網索引的特色是實時性高,數據量大。時效性要求用戶和客戶的各類行爲可以第一時間進入索引;數據量大要求一個有效分佈式方案能夠在常數時間內建立不斷增加的TB數量級索引。緩存

實時索引咱們採用 面向隊列的架構 ,數據首先寫入DB(或文件),而後經過數據庫同步機制將數據流寫入kafka隊列。這種同步機制和數據庫主從同步的原理相同,主要的開源產品有mypipe和阿里推出的canal。es經過訂閱相應的topic實現實時創建索引。性能優化

若是數據源是文件,則使用flume實時寫入Kafka。網絡

另一個索引問題是全量索引。有以下幾個場景讓 全量索引是一個必要過程 :session

  • 實時更新有可能會丟數據,每次不多的丟失時間長了下降搜索引擎的質量。 週期性的全量更新是解決這個問題的最直接的方法;
  • 即便可以保證明時更新,業務的發展有可能有從新建索引的需求(好比增長字段,修改屬性,修改分詞算法等)。
  • 不少搜索引擎是在業務開始後好久才搭建的,冷啓動必須全量建立索引。

咱們採用 Hadoop-es 利用hadoop分佈式的特性來建立索引。hadoop-es讓分佈式索引對用戶透明,就像單機更新索引同樣。一個是分佈式的數據平臺,一個是分佈式搜索引擎,若是能把這兩個結合就可以實現分佈式的全量索引過程。Hadoop-es正式咱們想要的工具。

咱們給出一個經過Hive sql建立索引的栗子 :

  1. drop table search.goods_index;
  2. CREATE EXTERNAL TABLE search.goods_index (
  3. is_virtual int,
  4. created_time string,
  5. update_time string,
  6. title string,
  7. tag_ids array
  8. ) STORED BY ‘org.elasticsearch.hadoop.hive.EsStorageHandler’ TBLPROPERTIES (
  9. ‘es.batch.size.bytes’=’1mb’,
  10. ‘es.batch.size.entries’=’0’,
  11. ‘es.batch.write.refresh’=’false’,
  12. ‘es.batch.write.retry.count’=’3’,
  13. ‘es.mapping.id’=’id’,
  14. ‘es.write.operation’=’index’,
  15. ‘es.nodes’=’192.168.1.10:9200’,
  16. ‘es.resource’=’goods/goods’);

系統把es映射成hive的一個外部表,更新索引就像是寫入一個hive表同樣。實際上全部分佈式問題都被系統透明瞭。

不建議從數據庫或文件系統來全量索引。一方面這會對業務系統形成很大的壓力,另外一方面由於數據庫和文件系統都不是真正分佈式系統,本身寫程序保證全量索引的水平擴展性很容易出問題,也沒有必要這麼作。

全量索引和增量索引的架構以下圖所示。另一點是hadoop也是訂閱kafka備份數據庫和日誌的。我我的建議一個公司全部DB和文件都存儲在hadoop上,這樣作起碼有二個 好處 :

  1. hadoop上使用hive或者spark建立的數據倉庫爲大數據提供統一的操做接口。
  2. hadoop數據相對於線上更加穩定,能夠做爲數據恢復的最後一個防線。

數據倉庫的話題不在本篇文章的討論範圍,這裏只是簡單提一下。

爲何咱們選擇Kafka?Kafka 是一個以高吞吐著名的消息系統。Kafka開啓了日誌合併(log compaction)功能後,能夠永久保存每條消息。每一條消息都有一個key,正好對應數據庫的主鍵,Kafka始終保存一個key最新的一條消息,歷史版本會被垃圾回收掉。有了這個特性,Kafka不只能夠保存數據庫最新的快照,並且能夠實現實時更新的消息系統。

第一次同步的時候,數據表中每行記錄都轉化成以主鍵爲key的消息進入Kafka,而且能夠被任意數量的broker消費。以後數據庫的每次更新(insert,updated,delete)都會被轉化成Kafka的消息。若是一行記錄頻繁被更改,Kafka會識別這些重複的消息,把舊的消息回收掉。

Kafka既保存數據庫最新的全量數據,又提供實時數據流的這個特性爲架構的可維護性提供極大便捷。若是你想從零掃描整個數據庫,你只須要從開始消費這個Kafka的topic便可完成,當讀到topic末端,自動得到實時更新的特性。

Kakfa的另外一個特性是 支持從任意斷點讀取數據 ,好比咱們全量索引是從HDFS中讀取,咱們能夠根據HDFS保存的數據的最後一條的時間戳,直接切換到Kafka讀取以後的數據。

高級搜索: 超越ES功能限制

高級搜索模塊(AS)在商業搜索引擎起到相當重要的做用。在各大商業搜索引擎公司裏面AS已經成爲標配,也是變動最爲頻繁的模塊。

AS在商業搜索引擎中主要起到以下做用:

  1. 反向代理,實現基於分片的分佈式搜索(實際上es有這個功能); 提供必要的容災支持
  2. 提供插件化的相關性計算框架
  3. 提供豐富的相關性庫,好比query分析庫,query改寫庫,排序庫,過濾庫等。
  4. 管理不一樣的搜索業務

AS 一個主要的功 能 是經過一個個業務插件來表明相應的搜索。一個最簡單的插件只須要包含對應的ES search API,它實際上就是一個配置項,說明es的地址。 這樣AS就是一個純代理。可是商業搜索的需求都是否是ES自己可以支持的,因此就須要根據需求寫相應的Query rewriter,rerank等算法插件。這樣就實現了框架和業務分離,AS具備極強的擴展性和複用性。

AS 另外一個功能 是提供通用算法庫,實際上它只爲每種算法提供編程框架。 算法也是經過插件的方式加入算法庫的。這種方法可讓算法工程師抽象公共算法庫供業務方使用,避免從新造輪子。一個具體業務要麼使用已經存在的算法(並修改參數),要麼本身實現算法。

上圖是一個 實例 。商品搜索和分銷搜索各自實現一個rerank的的算法,同時都調用了系統提供的rerank1的算法庫,並加入了本身特有的邏輯。

AS除了基本proxy功能外,還提供基於query的cache功能用於應用級別的緩存。內部有一個緩衝隊列,防止出現雪崩現象。下一節性能優化中會詳細說明。

ES性能優化

下面幾個小結,咱們寫了幾個咱們遇到的性能優化場景。

1.使用應用級隊列防止雪崩

ES一個問題是在高峯期時候極容易發生雪崩。ES有健全的線程池系統來保證併發與穩定性問題。 可是在流量突變的狀況下(好比雙十一秒殺)仍是很容易發生癱瘓的現象,主要的緣由以下:

  • ES幾乎爲每類操做配置一個線程池; 只能保證每一個線程池的資源使用時合理的,當2個以上的線程池競爭資源時容易形成資源響應不過來。
  • ES沒有考慮網絡負載致使穩定的問題。

在AS裏咱們實現了面向請求的全局隊列來保證穩定性。 它主要作了3件事情。

  1. 根據業務把請求分紅一個個slide,每一個slide對應一個隊列。 默認一個應用就是一個slide,一個應用也能夠區分不一樣的slide,這樣能夠保護一個應用內重要的查詢。
  2. 每一個隊列配置一個隊列長度,默認爲50。
  3. 每一個隊列計算這個隊列的平均響應時間。 當隊列平均響應時間超過200ms,中止工做1s,若是請求溢出就寫入溢出日誌留數據恢復使用。 若是連續10次隊列平均響應時間超過500ms就報警,以便工程師第一時間處理。

2.自動降級

應用級隊列解決雪崩問題有點粗暴,若是一個應用自己查詢就很是慢,很容易讓一個應用持續超時好久。咱們根據搜索引擎的特色編寫了自動降級功能。

好比商品搜索的例子,商品搜索最基本的功能是布爾查詢,可是還須要按照相關性分數和質量度排序等功能,甚至還有個性化需求。完成簡單的布爾查詢,ES使用bitsets操做就能夠作到,可是若是若是須要相關性分,就必須使用倒排索引,並有大量CPU消耗來計算分數。ES的bitsets比倒排索引快50倍左右。

對於有降級方案的slide,AS在隊列響應過慢時候直接使用降級query代替正常query。這種方法讓咱們在不擴容的狀況下成功度過了雙十一的流量陡增。

3.善用filtered query

理解lucence filter工做原理對於寫出高性能查詢語句相當重要。許多搜索性能優化都和filter的使用有關。filter使用bitsets進行布爾運算,quey使用倒排索引進行計算,這是filter比query快的緣由。 bitsets的優點 主要體如今:

  • bitsetcache在內存裏面,永不消失(除非被LRU)。
  • bitsets利用CPU原生支持的位運算操做,比倒排索引快個數量級
  • 多個bitsets的與運算也是很是的快(一個64位CPU能夠同時計算64個DOC的與運算)
  • bitsets 在內存的存儲是獨立於query的,有很強的複用性
  • 若是一個bitset片斷全是0,計算會自動跳過這些片斷,讓bitsets在數據稀疏狀況下一樣表現優於倒排索引。

舉個例子:

  1. query:bool:
  2. tag:'mac'
  3. region:'beijing'
  4. title: "apple"

lucence處理這個query的方式是在倒排索引中尋找這三個term的倒排鏈,並使用跳指針技術求交,在運算過程當中須要對每一個doc進行算分。實際上tag和region對於算分並無做用,他們充當是過濾器的做用。

這就是過濾器使用場景,它只存儲存在和不存在兩種狀態。 若是咱們把tag和region使用bitsets進行存儲,這樣這兩個過濾器能夠一直都被緩存在內存裏面,這樣會快不少。 另外tag和region之間的求交很是迅速,由於64位機器能夠時間一個CPU週期同時處理64個doc的位運算。

一個lucence金科玉律是: 能用filter就用filter,除非必須使用query(當且僅當你須要算分的時候)。

  1. query:
  2. filtered:
  3. query:
  4. title: "apple"
  5. filter:
  6. tag:"mac"
  7. region:"beijing"

lucence的filtered query會智能的先計算filter語句,而後才計算query語句,儘量在進行復雜的倒排算法前減小計算空間。

4.其餘性能優化

線上集羣關閉分片自動均衡。分片的自動均衡主要目的防止更新形成各個分片數據分佈不均勻。可是若是線上一個節點掛掉後,很容易觸發自動均衡,一時間集羣內部的數據移動佔用全部帶寬。建議採用閒時定時均衡策略來保證數據的均勻。

儘量延長refresh時間間隔。爲了確保實時索引es索引刷新時間間隔默認爲1秒,索引刷新會致使查詢性能受影響,在確保業務時效性保證的基礎上能夠適當延長refresh時間間隔保證查詢的性能。

除非有必要把all字段去掉。索引默認除了索引每一個字段外,還有額外建立一個all的字段,保存全部文本,去掉這個字段能夠把索引大小下降50%。

建立索引時候,儘量把查詢比較 慢 的索引和 快 的 索引物理分離 。

本文對es自己的優化寫的很少,由於es官網和其餘的博客有不少es優化的意見,就不在一一枚舉。本文的主要目的是可以對搭建商用電商搜索引擎給讀者一個通常性的建議,另外,困擾商用搜索引擎的最多見的問題是排序和算法問題。

算法體系架構

在上半部分中,咱們介紹了有贊搜索引擎的基本框架。搜索引擎主要3個部件構成。第一,hadoop集羣,用於生成大規模搜索和實時索引; 第二,ElasticSearch集羣,提供分佈式搜索方案; 第三,高級搜索集羣,用於提供商業搜索的特殊功能。

1.索引過程

建立索引過程從原始數據建立倒排索引的過程。這個過程當中咱們對商品(doc)進行分析,計算商品靜態分,並對商品進行類似度計算。商品的靜態分對於提高搜索引擎質量起到相當重要的做用,至關於網頁搜索的pagerank,想象一下若是沒有pagerank算法,網頁搜索的質量會有多麼差。在電商搜索中,最多見的問題是類似商品太多,必須在創建索引過程當中就對商品間的類似度進行預計算,以便在檢索過程當中進行有效去重。

建立索引的過程以下:

step 1,計算每一個doc的靜態分;

step 2,計算兩兩doc的類似度;

step 3,根據類似度和其餘信息對數據進行分庫;

step 4,創建ES索引。

2.檢索過程

檢索過程是搜索引擎接收用戶的query進行一系列處理並返回相關結果的過程。商業搜索引擎在檢索過程當中須要考慮2個因素:1) 相關性,2) 重要性。

相關性是指返回結果和輸入query是否相關,這是搜索引擎基本問題之一,目前經常使用的算法有BM25和空間向量模型。這個兩個算法ElasticSearch都支持,通常商業搜索引擎都用BM25算法。BM25算法會計算每一個doc和query的相關性分,咱們使用Dscore表示。

重要性是指商品被信賴的程度,咱們應該吧最被消費之信賴的商品返回給消費者,而不是讓消費之本身鑑別。尤爲是在商品充分競爭的電商搜索,咱們必須賦予商品合理的重要性分數,才能保證搜索結果的優質。重要性分,又叫作靜態分,使用Tscore表示。

搜索引擎最終的排序依據是:

Score = Dscore * Tscore

即綜合考慮靜態分和動態分,給用戶相關且重要的商品。

檢索的過程大體抽象爲以下幾個步驟。

step 1,對原始query進行query分析;

step 2,在as中根據query分析結果進行query重寫;

step 3,在as中使用重寫後的query檢索es;

step 4,在es查詢過程當中根據靜態分和動態分綜合排序;

step 5,在as中吧es返回的結果進行重排;

step 6,返回結果。

商品靜態分計算技術

在電商搜索引擎裏面商品的靜態分是有網頁搜索裏面的pagerank同等的價值和重要性,他們都是doc固有的和查詢query無關的價值度量。pagerank經過doc之間的投票關係進行運算,相對而言商品的靜態分的因素會更多一些。商品靜態計算過程和pagerank同樣 須要解決以下2個問題 :

  1. 穩定性 。pagerank能夠保證一個網站不會由於簡單連接堆砌能夠線性提高網站的排名。一樣,商品靜態分的計算不可讓商品能夠經過增長單一指標線性增長分值(好比刷單對搜索引擎的質量的影響)。
  2. 區分度 。在保證穩定性的基礎上商品靜態分要有足夠的區分度能夠保證一樣搜索的條件下,排在前面的商品的質量比排在後面的商品的質量高。

咱們假設商品的靜態分有3個決定性因素:1,下單數;2,好評率;3,發貨速度。

靜態分咱們使用Tsocre表示,Tscore能夠寫成以下形式:

Tscore = a * f(下單數) + b * g(好評率) + c * h(發貨速度)

a,b,c是權重參數,用於平衡各個指標的影響程度。f,g,h是表明函數用於把原始的指標轉化成合理的度量。

首先,咱們須要尋找合理的表明函數。

  1. 首先對各個指標取log。log的導數是一個減函數,表示爲了得到更好的分數須要花費愈來愈多的代價。
  2. 標準化。標準化的目的讓各個度量能夠在同一區間內進行比較。好比下單數的取值是0~10000,而好評率的取值爲0~1。這種狀況會影響到數據分析的結果和方便性,爲了消除指標之間的量綱的影響,須要進行數據標準化處理,以解決數據指標之間的可比性。最經常使用的標準化方法是z-score標準化方法。

z-score 標準化方法

「機率論」告訴咱們對於知足正態分佈的數據來講,均值先後3個z-score的範圍能夠覆蓋99%的數據。經驗地,咱們把>5個zscore 或者小於 -5個zscore的分數設置成5*zscore或者-5zscore。特別說明的是,咱們不建議使用min-max標準化方法。這種方法又叫離差標準化,是對原始數據的線性變換,使結果值映射到[0-1]之間,轉化函數以下:

這種方法很是不穩定,假設一個奇異點是第二大的值的1000倍,會讓大部分的值都集中在0~0.01,一樣失去了歸一化的目的。

圖一是使用min-max歸一化後的數據分佈,顯然大部分數據被」壓扁」在很小的範圍; 圖二使用log歸一化後的數據分佈,因爲log緩解了增加速度,能夠看出來已經有一個不錯的結果了;圖三是在log的基礎上進行z-score歸一化,能夠看出來,z-score讓數據變得很是平滑。

(圖一: min-max歸一化)

(圖二: log歸一化)

(圖三: log-zscore歸一化)

最後,選擇合適的權重 通過log-zscore歸一化之後,咱們基本上吧f,g,h的表示的表明函數說明清楚。Tscore = af(下單數) + bg(好評率) + c*h(發貨速度),下一步就是肯定a,b,c的參數。通常有兩個方法:

  1. 專家法。根據咱們的平常經驗動態調整權重參數;
  2. 實驗法。首先在專家的幫助下賦一個初始值,而後改變單一變量的方法根據abtest的結果來動態調整參數。

商品標題去重

商品標題去重在電商搜索中起到重要做用,根據數據,用戶經過搜索頁購買商品80%選擇搜索的前4頁。商品標題的重複會致使重要的頁面沒有含金量,極大下降了搜索的購買率。

舉個例子:

Title1:美味/香蕉/包郵/廣東/高州/香蕉/banana//無/催熟劑/

Title2:美味/香蕉/廣東/高州/香蕉//非/粉蕉/包郵/

這裏用到 「bag of word」 技術,將詞彙表做爲空間向量的維度,標題的每一個term的詞頻做爲這個feature的值。以這個例子來講。這個詞彙的維度爲: 美味(0),香蕉(1),包郵(2),廣東(3),高州(4),banana(5),無(6),催熟劑(7),非(8),粉蕉(9) 位置: 0,1,2,3,4,5,6,7,8,9

Title1: 1,2,1,1,1,1,1,1,0,0

Title2: 1,2,1,1,1,0,0,0,1,1

這個每一個title都用一個固定長度的向量表示。

再次,計算兩兩類似度。

類似度通常是經過計算兩個向量的距離實現的,不失通常性,在這裏咱們使用1-cosine(x,y)來表示兩個向量的距離。這是一個」All Pair Similarity」的問題,即須要兩兩比較,複雜度在O(n^2)。在商品量巨大的時候單機很難處理。咱們給出兩種方法用於實現」All Pair Similarity」。

方法一:spark的矩陣運算。

rddRows = sc.parallelize([「1 0 2 0 0 1」, 「0 0 4 2 0 0″])

rddRows.map(lambda x: Vectors.dense([float(each) for each in str(x).split(」 「)]))

mat = RowMatrix(rddRows)

simsPerfect = mat.columnSimilarities()

方法二:map-reduce 線性方法。

這個方法參考論文」Pairwise Document Similarity in Large Collections with MapReduce」。能夠實現幾乎線性的時間複雜度。相對於矩陣運算在大規模(10億以上)pair similarity 運算上面有優點。這個方法簡單的描述以下: 首先,按照倒排索引的計算方式計算每一個term到doc的映射。好比3個doc:

doc1 = 我 愛 北京

doc2 = 我 北京 天安門

doc3 = 我 天安門

轉化爲倒排格式,這個須要一次mapper reduce

我 -> doc1, doc2, doc3

愛 -> doc1

北京 -> doc1, doc2

天安門 -> doc2, doc3

而後,對於value只有一個元素的過濾掉,對於value大於2個doc的兩兩組合:

doc1,doc2 <—- from: 我 -> doc1, doc2, doc3

doc1,doc3 <—- from: 我 -> doc1, doc2, doc3

doc2,doc3 <—- form: 我 -> doc1, doc2, doc3

doc1,doc2 <—- from: 北京 -> doc1, doc2

doc2,doc3 <—- from: 天安門 -> doc2, doc3

最後,對於輸出進行聚合,value爲重複次數和兩個doc乘積開根號的比。

doc1,doc2 -> 2/(len(doc1)*len(doc2))^1/2 = 0.7

doc1,doc3 -> 1/(len(doc1)*len(doc3))^1/2 = 0.3

doc2,doc3 -> 2/(len(doc2)*len(doc3))^1/2 = 0.3

對於2個title1,title2,若是X(title1,title2) > 0.7 則認爲title1和title2類似,對於類似的兩個doc,靜態分大的定義爲主doc,靜態分小的定義爲輔doc。主doc和輔doc分別建庫。

區別於網頁搜索(網頁搜索直接將輔doc刪除),咱們將主doc和輔doc分別建庫。每一次搜索按比例分別搜主庫和輔庫,並將結果融合返回。這樣能夠保證結果的多樣性。

店鋪去重

店鋪去重和商品標題去重有點不一樣。因爲電商特定場景的須要,不但願搜索結果一家獨大,這樣會引起強烈的馬太效應。店鋪去重不能使用如上的方法進行。由於上面的方法的主要依據是文本類似,在結果都相關的前提下,進行適當的取捨。可是店鋪去重不是這樣的特性。

設想一下,若是咱們根據店鋪是否相同,把同一店鋪的商品分到主庫和從庫中,以下圖所示。

A和B表明不一樣的店鋪。

在搜索香蕉的時候,的確能夠控制A店鋪結果的數量,可是在搜索」梨」的時候就錯誤的吧B店鋪的梨排在前面了(假設A:梨比B:梨靜態分高)。

實際上想達到店鋪去重的效果經過分桶搜索是很容易作的事情。咱們假設每頁搜索20個結果,咱們把索引庫分紅4個桶,每一個商品對桶數取模獲得所在桶的編號。這樣能夠保證同一店鋪的商品僅在一個桶裏面。搜索的過程每一個桶平均分攤搜索任務的25%,並根據靜態分合併成一頁的結果。這樣同一保證結果的相對順序,又達到了店鋪去重的目的。

如上圖所示,搜索」香蕉」,雖然A店鋪有10個知足需求的結果,可是每頁搜索醉倒只有5個結果能夠展現。

query分析與Query改寫技術

上面介紹了幾個創建索引過程當中幾項技術,檢索過程當中的關鍵技術有不少。其中最著名的是query分析技術。咱們使用的query分析技術主要包括核心詞識別,同義詞拓展,品牌詞識別等等。query分析技術大部分都是NLP研究範圍,本文就不詳細闡述不少理論知識。咱們重點介紹同義詞拓展技術。這個技術通常都須要根據本身的商品和和用戶日誌特定訓練,沒法像分詞技術和品牌詞識別同樣有標準的庫能夠適用。

同義詞拓展通常是經過分析用戶session日誌獲取。若是一個用戶輸入」蘋果手機」沒有獲得想要的結果,他接着輸入」iphone」,咱們在」蘋果手機」和」iphone」之間建立一個轉移關係。基於統計,咱們能夠把用戶query建立一個相互聯繫的權重圖。

用戶輸入query 「蘋果手機」,根據query分析,」蘋果手機」有 「iphone」0.8,」iphone 6″0.5 兩個同義詞。0.8和0.5分別表示同義的程度。咱們想要」蘋果手機」,」iphone」,」iphone 6」 3個query同時輸入,而且按照同義的程度對不一樣的query賦予不一樣的權重。ElasticSearch提供的BoostingQuery能夠支持這個需求。

原始的query:

  1. {
  2. 「query」{
  3. 「match」: {
  4. 「query」: 」蘋果手機」
  5. }
  6. }
  7. }

優化後的query:

  1. {
  2. "query": {
  3. "should": [
  4. {
  5. "match": {
  6. "content": {
  7. "query": "蘋果手機",
  8. "boost": 10
  9. }
  10. }
  11. },
  12. {
  13. "match": {
  14. "content": {
  15. "query": "iphone",
  16. "boost": 8
  17. }
  18. }
  19. },
  20. {
  21. "match": {
  22. "content": {
  23. "query": "iphone6",
  24. "boost": 5
  25. }
  26. }
  27. }
  28. ]
  29. }
  30. }

其餘好比核心詞識別,歧義詞糾正等方法差很少,本文不作詳細闡述。

小結

商業電商搜索算法另外兩個重要技術,一個是類目體系創建和應用,另外一個是個性化技術。這個兩項技術咱們還處在探索階段。類目體系咱們主要使用機器學習的方法進行訓練,個性化主要經過用戶畫像進行Query改寫來實現。等咱們上線有效果在與你們分享。

搜索算法是一個很是值得一個電商產品持續投入的技術。一方面若是技術人員要有良好的技術背景,能夠借鑑不少成熟的技術,避免重複造輪子; 另外一方面,每一個產品的搜索都有自身的特色,須要深刻研究產品的特性給出合理的解決方案。

相關文章
相關標籤/搜索