2013-11-27 159 views
0

我們有一個非常簡單的產品目錄,用於存儲mysql表格中的產品,我們需要爲儘可能快地(儘可能相關)工作的產品構建高質量的搜索。產品數據庫將會非常大(大約500,000個產品),這就是爲什麼使用「不喜歡」索引的「like」進行搜索非常緩慢。我們已經嘗試過使用mysql全文搜索來快速運行,但沒有產生令人滿意的結果,特別是對於使用數字的搜索(例如「LR-41」,這是一種電池類型)。調優獅身人面像搜索產品搜索

我們的產品目錄包括很多領域,但我們需要在搜索,僅僅是:

product_id = bigint 
title = varchar(255) 
description = text 

許多建議後,我們終於用Sphinx搜索嘗試,並提出了配置,如:

source mysearch { 
    type=mysql 
    sql_host=... 
    sql_user=... 
    sql_pass=... 
    sql_port=... 
    sql_query_pre = SET NAMES utf8 
    sql_query = SELECT product_id, title, description FROM products 
    sql_query_info = SELECT * FROM products WHERE product_id=$id 
} 

index fulltext { 
    source = mysearch 
    path = /var/lib/sphinxsearch/data/mysearch 
    docinfo = extern 
    mlock = 0 
    morphology = stem_en, metaphone 
    min_word_len = 1 
    blend_chars = +, &, U+23, - 
    blend_mode = trim_both 
    html_strip = 1 
} 

indexer { 
    mem_limit = 256M 
} 

searchd { 
    listen = 9312 
    # everything else set to default 
} 

對於網站後端我們使用PHP,我們使用下面的代碼:

<?php 
$sphinx = new SphinxClient(); 
$sphinx->SetServer('localhost', 9312); 
$sphinx->SetMatchMode(SPH_MATCH_EXTENDED); 
$sphinx->setFieldWeights(array(
    'product_id' => 10, 
    'title' => 7, 
    'description' => 3 
)); 
$sphinx->setLimits(0, 200, 1000, 5000); 
$sphinx->SetRankingMode(SPH_RANK_PROXIMITY_BM25); 
$sphinx->AddQuery($_GET['query'], "fulltext"); 
$results = $sphinx->RunQueries(); 
print_r($results); 
?> 

這只是一個演示腳本來測試搜索,但它返回完全錯誤的結果,無論我用於查詢 - 它匹配的產品甚至不包括我正在尋找的一個詞(或子字符串)。

下面是規則我想達到的目標:

  • 如果查詢「PRODUCT_ID」產品應列爲首位(有些頻繁的用戶都知道的product_id,並希望通過它來搜索)
  • 匹配如果查詢是「Meter XY-123」,它應該匹配所有包含這兩個詞或任何這些詞的產品(自然包含這兩個詞串的產品應排名較高)
  • 如果在標題中發現查詢,應該排名高於如果在說明中發現
  • 如果有人搜索「XY-123」,它應該產生相同的結果,就像他搜索「XY123」或「XY123」一樣,它也應該搜索子串 - 例如,如果產品的標題是「Foobar的123」,即使對於「富杆123」,「條123」,「foobar的12」,「福」等用戶搜索
  • 結果也應返還被某種下令應退還相關性..例如如果我有兩個產品「foobar 123」和「foobar 456」,並且用戶搜索「foobar 4」,那麼兩個產品應該返回(匹配任何單詞),但第二個產品應該排名較高(因爲它也包含數字4)第一個(不包含數字4)。
  • 產品應該還可以基於哪個字段的值被找到的排名。在這種情況下PRODUCT_ID字段具有比具有比描述也較高的權重更大的標題重量。

所以問題是 - 如何正確配置和使用sphinx + php來產生符合上述標準的搜索結果?

謝謝!

回答

1

這僅僅是一個演示腳本來測試搜索,但它返回無論我使用的查詢

完全錯誤的研究結果表明,從morphology刪除metaphone。這特別使'模糊'索引 - 有點像'聲音一樣'。但它不適合與stemming(即stem_en)相結合 - 導致非常混亂的結果。

事實上,如果設置前綴索引(如下所示),也可以刪除詞幹分析 - 如果嘗試並使用兩者,則很難檢測到邊界情況。


如果查詢匹配「PRODUCT_ID」產品應列爲首位(有些頻繁的用戶都知道的product_id,並希望通過它來搜索)

獅身人面像犯規包含產品ID在'全文'索引。你需要複製它。

sql_query = SELECT product_id as id, product_id, name,... 

如果查詢是「儀表XY-123」,它應該匹配所有包含兩個或任何的這些話(當然產品包含兩個字符串應該排名更高)

產品

這意味着你想做一個'任何'搜索。獅身人面像默認爲'ALL'搜索。要麼改變SPH_MATCH_ANY,或重寫查詢,使其「任意」(注「|」字或使用定額之間)


如果有人搜索「XY-123」,它應該產生相同的結果。如果他搜索「XY123」或「XY 123」

這非常狡猾。您可以嘗試添加 - 到blend_chars。哪種工作方式。但輸入說「XY 123」將不符合「XY123」的產品。我不認爲有這個簡單的解決方案。

有各種統計方法來嘗試重寫查詢,但由其本質將是不準確的。


它768,16還搜索串 - 例如如果產品的標題是「Foobar的123」它應該返回即使「富杆123」,「條123」,「foobar的12」,「福」等

需要使用min_prefix_len用戶搜索啓用前綴搜索,並設置enable_star = 0

enable_star=0被depereciated,因此,或許可以使用expand_keywords=1代替它會自動添加星爲您服務。


結果也應返回的某種相關性

的一般會發生排序。但可以嘗試改變排名模式下,如果想 - 有很多選項(但需要使用擴展匹配模式)


產品也應在此基礎上字段中的值中發現的排名

setFieldWeights來救援! (你已經知道了!)

+0

thanx!我會嘗試你的建議,並會讓你知道結果... – j99