關於多屬性查找問題的sphinx解決方案

需求描述php

mysql中,每個文檔都有多個標籤,查詢時能夠篩選一個標籤也能夠篩選同時擁有多個標籤的文檔。mysql

數據示例sql

文檔         標籤
1             1,2,3,4,5
2             2,3,4,5,6
3             3,4,5,6,7
4             4,5,6,7,8
5             5,6,7,8,9

注意:
這裏將文檔id和標籤tagid的對應關係存入了fy_content_tag表,一個id對應多條tagid記錄數據庫

查詢要求api

一、查出擁有標籤2的文檔
二、查出同時擁有標籤2,3,4的文檔服務器

使用sphinx解決需求函數

一、配置shpinx mva多值屬性學習

編輯sphinx配置文件,給數據源增長一個多值屬性ui

sql_attr_multi = uint tagid from query;\
       SELECT id,tagid FROM fy_content_tag

二、執行查詢spa

使用API中的setFilter便可。

一、查出擁有標籤2的文檔

$sphinx->setFilter('tagid', array(2));

二、查出同時擁有標籤2,3,4的文檔

$sphinx->setFilter('tagid', array(2));
$sphinx->setFilter('tagid', array(3));
$sphinx->setFilter('tagid', array(4));

這裏解釋一下:
$sphinx->setFilter(‘tagid’, array(2,3,4));
是表示含有標籤值2,3,4中的任意一個即符合篩選,這裏是or關係。

$sphinx->setFilter(‘tagid’, array(2));
$sphinx->setFilter(‘tagid’, array(3));
$sphinx->setFilter(‘tagid’, array(4));
設置三個filter是標示,要同時知足2,3,4三個屬性值才符合,這裏是and關係。

————————————

Sphinx sql_attr_multi配置參考

在Sphinx中,有一個MVA屬性,聲明格式以下(用反斜線只是爲了清晰,您仍能夠在一行以內完成聲明):
sql_attr_multi = ATTR-TYPE ATTR-NAME ‘from’ SOURCE-TYPE \
[;QUERY] \
[;RANGE-QUERY]
其中
ATTR-TYPE 是 ‘uint’ 或 ‘timestamp’之一
SOURCE-TYPE 是 ‘field’, ‘query’, 或 ‘ranged-query’之一
QUERY 是用來取得所有(文檔 ID,屬性值)序對的 SQL 查詢
RANGE-QUERY 是用來取得文檔 ID 的最小值與最大值的 SQL 查詢,
與’sql_query_range’相似
示例:
sql_attr_multi = uint tag from field;
sql_attr_multi = uint tag from query; SELECT id, tag FROM tags
sql_attr_multi = uint tag from ranged-query; \
SELECT id, tag FROM tags WHERE id>=$start AND id<=$end; \
SELECT MIN(id), MAX(id) FROM tags

使用field類型時,field字段的值應該是以英文逗號隔開的多個無符號32位整數,如:1,2,3,4

使用query或者ranged-query時,每行一個值,一個id對應多個(多行)tag值

 

上面講的都是一些理論,實際工做中咱們不須要再建立一張表,而是增長一個字段就能夠了:

Sphinx MVA(聲明多值屬性)的用法
最近開始學習Sphinx,因而安裝了「Coreseek 全文檢索服務器 2.0「,詳情可訪問Coreseek官網,喬老大真的很熱心,有問題能夠POST在BBS,也能夠加他的MSN,他都會耐心的爲你解答,真是可貴的好人。
  回到主題,在Mysql數據庫中,有SET(集合)類型,能夠保存多個值,使用FIND_IN_SET函數查找也很方便。在使用Sphinx中,有一個MVA屬性,聲明格式以下(用反斜線只是爲了清晰,您仍能夠在一行以內完成聲明):
sql_attr_multi = ATTR-TYPE ATTR-NAME 'from' SOURCE-TYPE \
[;QUERY] \
[;RANGE-QUERY]
其中
ATTR-TYPE 是 ‘uint’ 或 ‘timestamp’之一
SOURCE-TYPE 是 ‘field’, ‘query’, 或 ‘ranged-query’之一
QUERY 是用來取得所有(文檔 ID,屬性值)序對的 SQL 查詢
RANGE-QUERY 是用來取得文檔 ID 的最小值與最大值的 SQL 查詢,
與’sql_query_range’相似
示例:
sql_attr_multi = uint tag from field;
sql_attr_multi = uint tag from query; SELECT id, tag FROM tags
sql_attr_multi = uint tag from ranged-query; \
SELECT id, tag FROM tags WHERE id>=$start AND id<=$end; \
SELECT MIN(id), MAX(id) FROM tags
使用第一種仍是比較方便,因爲沒有說明,當時也試了好久,字段值的存放格式是:
| tag |
|1,2,3,4,5,6|
使用field類型,就能夠實現了。這裏的分隔符不單單可使用逗號,還可使用空格,或者其餘字符,如:
| tag |
|1%3%14 60|
Sphix也是能夠識別的,不過,仍是統一用分隔符比較好。^-^

 

 

如何在sphinxse中使用?

在sphinxSE中用WHERE query='filter=ids,2345,5334' 便可實現SQL中WHERE ids IN (2345,5334)的效果。

 

修改sphinx最大輸出記錄數

概括以下:
Sphinx的查詢默認最大記錄數是:1000,而咱們想更改這個數值。就須要更改三個地方。
1是更改sphinx.conf配置文件的:max_matches   = 10000 #後面數字就是你想查詢的最大記錄數。建議在1000~10000以內。
2是在api調用時,$cl->SetLimits($pageStart, $pageSize, $max_limits);用SetLimits的第三個參數更改成你想要的顯示最大記錄數。
3 修改sphinxclient.php 中max_matches
 
問題是這樣的,信息列表頁的分頁裏顯示有100多頁,但到51頁的時候不顯示正確的信息列表了。按慣例,輸出結果,查看可疑之處。發現返回的結果裏total永遠都是1000,total_found大概是分頁中顯示的頁數和每頁信息數的乘積,這說明total_found返回的是真正的信息數,但查詢結果的時候又受到了total的限制。
百度sphinx total_found,得知sphinx有個max_matches是限制匹配結果數的,看了sphinx.conf,發現其中設置的max_matches遠大於查詢結果數,看來代碼中有設置了,又查看sphinx的應用類,發現了SetLimits($start, $limit, 1000)這個東東,原來max_matches在這兒被定成了1000。
聽說max_matches設定太大的話,查詢速度會受影響,想了想把這個值設成變量,等於要查詢的頁數和每頁信息數的乘積,這樣就能獲得正確的結果了,並且不會影響小頁碼的頁面原查詢速度。
http://www.ourjour.com/tag/sphinx-max_matches/
相關文章
相關標籤/搜索