以上一篇的email數(shù)據(jù)表為例:
數(shù)據(jù)結(jié)構(gòu):
01.
CREATE
TABLE
email (
02.
emailid mediumint(8) unsigned
NOT
NULL
auto_increment COMMENT
'郵件id'
,
03.
?
04.
fromid
int
(10) unsigned
NOT
NULL
default
'0'
COMMENT
'發(fā)送人ID'
,
05.
?
06.
toid
int
(10) unsigned
NOT
NULL
default
'0'
COMMENT
'收件人ID'
,
07.
content text unsigned
NOT
NULL
COMMENT
'郵件內(nèi)容'
,
08.
subject
varchar
(100) unsigned
NOT
NULL
COMMENT
'郵件標題'
,
09.
?
10.
sendtime
int
(10)
NOT
NULL
COMMENT
'發(fā)送時間'
,
11.
?
12.
attachment
varchar
(100)
NOT
NULL
COMMENT
'附件ID,以逗號分割'
,
PRIMARY
KEY
(emailid),
13.
) ENGINE=MyISAM';
使用打開控制臺,必需打開控制臺PHP才能連接到sphinx(確保你已經(jīng)建立好索引源):
d:\coreseek\bin\searchd -c d:\coreseek\bin\sphinx.conf
coreseek/api目錄下提供了PHP的接口文件 sphinxapi.php,這個文件包含一個SphinxClient的類
在PHP引入這個文件,new一下
01.
$sphinx
=
new
SphinxClient();
02.
?
03.
//sphinx的主機名和端口
04.
?
05.
$sphinx
->SetServer (
'loclahost'
, 9312 );
06.
?
07.
//設(shè)置返回結(jié)果集為php數(shù)組格式
08.
?
09.
$sphinx
->SetArrayResult ( true );
10.
?
11.
//匹配結(jié)果的偏移量,參數(shù)的意義依次為:起始位置,返回結(jié)果條數(shù),最大匹配條數(shù)
12.
?
13.
$sphinx
->SetLimits(0, 20, 1000);
14.
?
15.
//最大搜索時間
16.
?
17.
$sphinx
->SetMaxQueryTime(10);
18.
?
19.
?
20.
?
21.
//執(zhí)行簡單的搜索,這個搜索將會查詢所有字段的信息,要查詢指定的字段請繼續(xù)看下文
22.
?
23.
$index
=
'email'
//索引源是配置文件中的 index 類,如果有多個索引源可使用,號隔開:'email,diary' 或者使用'*'號代表全部索引源
24.
?
25.
$result
=
$sphinx
->query (
'搜索關(guān)鍵字'
,
$index
);
26.
?
27.
echo
'
';
print_r($result);
echo '
';
$result是一個數(shù)組,其中
total是匹配到的數(shù)據(jù)總數(shù)量
matches是匹配的數(shù)據(jù),包含id,attrs這些信息
words是搜索關(guān)鍵字的分詞
你可能奇怪為什么沒有郵件的內(nèi)容這些信息,其實sphinx并不會返回像mysql那樣的數(shù)據(jù)數(shù)組,因為sphinx本來就沒有記錄完整的數(shù)據(jù),只記錄被分詞后的數(shù)據(jù)。
具體還要看matches數(shù)組,matches中的ID就是指配置文件中sql_query SELECT語句中的第一個字段,我們配置文件中是這樣的
sql_query = SELECT emailid,fromid,toid,subject,content,sendtime,attachement FROM email
所以matches中的ID是指emailid
至于weight是指匹配的權(quán)重,一般權(quán)重越高被返回的優(yōu)先度也最高,匹配權(quán)重相關(guān)內(nèi)容請參考官方文檔
attrs是配置文件中sql_attr_ 中的信息,稍后會提到這些屬性的用法
說了這么多,即使搜索到結(jié)果也不是我們想要的email數(shù)據(jù),但事實sphinx是不記錄真實數(shù)據(jù)的,所以要獲取到真實email數(shù)據(jù)還要根據(jù)matches中的ID去搜索mysql的email表,但總體來說這樣一來一回的速度還是遠遠比mysql的LIKE快得多,前提是幾十萬數(shù)據(jù)量以上,否則用sphinx只會更慢。
接下來介紹sphinx一些類似mysql條件的用法
01.
//emailid的范圍
02.
?
03.
$sphinx
->SetIdRange(
$min
,
$max
);
04.
?
05.
?
06.
?
07.
//屬性過濾,可過濾的屬性必需在配置文件中設(shè)置sql_attr_??? ,之前我們定義了這些
08.
?
09.
sql_attr_uint??????????? = fromid
10.
?
11.
sql_attr_uint??????????? = toid
12.
?
13.
sql_attr_timestamp? = sendtime
14.
?
15.
//如果你想再次修改這些屬性,配置完成后記得重新建立索引才能生效
16.
?
17.
?
18.
?
19.
//指定一些值
20.
?
21.
$sphinx
->SetFilter(
'fromid'
,
array
(1,2));???
//fromid的值只能是1或者2
22.
?
23.
//和以上條件相反,可增加第三個參數(shù)
24.
?
25.
$sphinx
->SetFilter(
'fromid'
,
array
(1,2), false);???
//fromid的值不能是1或者2
26.
?
27.
//指定一個值的范圍
28.
?
29.
$sphinx
->SetFilterRange(
'toid'
, 5, 200);???
//toid的值在5-200之間
30.
?
31.
//和以上條件相反,可增加第三個參數(shù)
32.
?
33.
$sphinx
->SetFilterRange(
'toid'
, 5, 200, false);???
//toid的值在5-200以外
34.
?
35.
?
36.
?
37.
//執(zhí)行搜索
38.
?
39.
$result
=
$sphinx
->query(
'關(guān)鍵字'
,
'*'
);
排序模式
可使用如下模式對搜索結(jié)果排序:
SPH_SORT_RELEVANCE 模式, 按相關(guān)度降序排列(最好的匹配排在最前面)
SPH_SORT_ATTR_DESC 模式, 按屬性降序排列 (屬性值越大的越是排在前面)
SPH_SORT_ATTR_ASC 模式, 按屬性升序排列(屬性值越小的越是排在前面)
SPH_SORT_TIME_SEGMENTS 模式, 先按時間段(最近一小時/天/周/月)降序,再按相關(guān)度降序
SPH_SORT_EXTENDED 模式, 按一種類似SQL的方式將列組合起來,升序或降序排列。
SPH_SORT_EXPR 模式,按某個算術(shù)表達式排序
01.
//使用屬性排序
02.
?
03.
//以fromid倒序排序,注意當再次使用SetSortMode會覆蓋上一個排序
04.
?
05.
$sphinx
->SetSortMode (
"SPH_SORT_ATTR_DESC"
,
'fromid'
);
06.
?
07.
//如果要使用多個字段排序可使用SPH_SORT_EXTENDED模式
08.
?
09.
//@id是sphinx內(nèi)置關(guān)鍵字,這里指emailid,至于為什么是emailid,自己思考一下
10.
?
11.
$sphinx
->SetSortMode (
"SPH_SORT_ATTR_DESC"
,
'fromid ASC, toid DESC, @id DESC'
);
12.
?
13.
//執(zhí)行搜索
14.
?
15.
$result
=
$sphinx
->query(
'關(guān)鍵字'
,
'*'
);
//更多請查看官方文檔排序模式的說明
匹配模式
有如下可選的匹配模式:
SPH_MATCH_ALL, 匹配所有查詢詞(默認模式);
SPH_MATCH_ANY, 匹配查詢詞中的任意一個;
SPH_MATCH_PHRASE, 將整個查詢看作一個詞組,要求按順序完整匹配;
SPH_MATCH_BOOLEAN, 將查詢看作一個布爾表達式
SPH_MATCH_EXTENDED, 將查詢看作一個CoreSeek/Sphinx內(nèi)部查詢語言的表達式 . 從版本Coreseek 3/Sphinx 0.9.9開始, 這個選項被選項SPH_MATCH_EXTENDED2代替,它提供了更多功能和更佳的性能。保留這個選項是為了與遺留的舊代碼兼容——這樣即使Sphinx及其組件包括API升級的時候,舊的應用程序代碼還能夠繼續(xù)工作。
SPH_MATCH_EXTENDED2, 使用第二版的“擴展匹配模式”對查詢進行匹配.
SPH_MATCH_FULLSCAN, 強制使用下文所述的“完整掃描”模式來對查詢進行匹配。注意,在此模式下,所有的查詢詞都被忽略,盡管過濾器、過濾器范圍以及分組仍然起作用,但任何文本匹配都不會發(fā)生.
我們要關(guān)注的主要是SPH_MATCH_EXTENDED2擴展匹配模式,擴展匹配模式允許使用一些像mysql的條件語句
01.
//設(shè)置擴展匹配模式
02.
?
03.
$sphinx
->SetMatchMode (
"SPH_MATCH_EXTENDED2"
);
04.
?
05.
//查詢中使用條件語句,字段用@開頭,搜索內(nèi)容包含測試,toid等于1的郵件:
06.
?
07.
$result
=
$sphinx
->query(
'@content (測試) & @toid =1'
,
'*'
);
08.
?
09.
//用括號和&(與)、|、(或者)、-(非,即!=)設(shè)置更復雜的條件
10.
?
11.
$result
=
$sphinx
->query(
'(@content (測試) & @subject =呃) | (@fromid -(100))'
,
'*'
);
12.
?
13.
//更多語法請查看官方文檔匹配模式的說明
擴展匹配模式中值得一提的是搜索的字段,如果該字段被設(shè)置屬性,那么擴展匹配搜索的字段默認是不包含這些屬性的,只能用SetFilter()或者SetFilterRange()之類
之前我們設(shè)置了fromid、toid、sendtime為屬性,但又想在擴展匹配模式中又想用作條件該怎么辦?
只要在sql_query語句中再選擇多一次該字段就可以了
sql_query = SELECT emailid,fromid,fromid,toid,toid,subject,content,sendtime,sendtime,attachement FROM email
//設(shè)置完成記得重新建立索引
更多條件技巧
只是一些技巧,但不建議使用的部署環(huán)境中,至于為什么,請看文章結(jié)尾
<、<=、>、>=
默認sphinx沒有這些比較符。
假如我想郵件的發(fā)送時間大于某一日期怎么辦?用SetFilterRange()方法模擬一下
01.
//大于等于某一時間截$time
02.
?
03.
$sphinx
->SetFilterRange(
'sendtime'
,
$time
, 10000000000)
//時間截最大是10個9,再加1是不可超越了。。
04.
?
05.
?
06.
?
07.
//大于某一時間截$time
08.
?
09.
$sphinx
->SetFilterRange(
'sendtime'
,
$time
+1, 10000000000)
10.
?
11.
//小于等于某一時間截$time
12.
?
13.
$sphinx
->SetFilterRange(
'sendtime'
, -1,
$time
)???
//時間截最小是0,所以應該減1
14.
?
15.
//大于某一時間截$time
16.
?
17.
$sphinx
->SetFilterRange(
'sendtime'
, -1,
$time
- 1)
IS NOT NULL
怎樣搜索為空的字段,比如我要搜索附件為空的郵件,有人可能會想 @attachment ('')不就可以了嗎?其實這是搜索兩個單引號。。。sphinx搜索的字符串不用加引號的
目前sphinx是沒有提供這樣的功能,其實可以在mysql語句上作手腳:
sql_query = SELECT emailid,fromid,toidsubject,content,sendtime,attachement != '' as attach is not null FROM email //這里返回了一個新字段attachisnotnull,當attachisnotnull為1的時候附件就不為空了
//設(shè)置完成記得重新建立索引
FIND_IN_SET()
搜索包含某一附件的郵件,mysql習慣用FIND_IN_SET這么簡單一句就搞定了,在sphinx中必需在配置里設(shè)置屬性sql_attr_multi 多值屬性(MVA):
sql_attr_multi = attachment #attachment可以是逗號分隔的附件ID,或者是空格、分號等sphinx都能識別
01.
//設(shè)置完成記得重新建立索引
02.
?
03.
?
04.
?
05.
然后PHP中可以使用SetFilter()
06.
?
07.
//搜索包含附件ID為1或2郵件,mysql語法是這樣FIND_IN_SET(`attachment`, '1,2')
08.
?
09.
$sphinx
->SetFilter(
'attachment'
,
array
(1,2))
10.
?
11.
//可以使用SetFilterRange,搜索包含附件ID在50-100范圍的郵件
12.
?
13.
$sphinx
->SetFilterRange(
'attachment'
, 50, 100)
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
