本文實例講述了PHP+MySQL+sphinx+scws實現全文檢索功能。分享給大家供大家參考,具體如下:
我的個人環境是PHP7.1+MariaDB10.1.23
下載安裝資源包
- sphinx地址
http://sphinxsearch.com/downloads/release/
- PHP的sphinx擴展下載
http://pecl.php.net/package/sphinx
- SCWS 下載地址
http://www.xunsearch.com/scws/download.php
- SCWS 詞庫下載地址
http://www.xunsearch.com/scws/down/scws-dict-chs-utf8.tar.bz2
安裝過程
因為我的是PHP 7 版本,安裝sphinx的時候遇到點問題
-
安裝
sphinx
1
2
3
4
5
6
7
|
[root@MevHost sphinxb] # mkdir -p /usr/local/src/sphinx [root@MevHost sphinxb] # cd /usr/local/src/sphinx [root@MevHost sphinxb] # tar -xf sphinx-2.2.11-release.tar.gz [root@MevHost sphinxb] # cd sphinx-2.2.11-release // 這里是指定安裝的目錄,還有引用mysql,(我這里是mariadb的安裝目錄) [root@MevHost sphinxb] # ./configure --prefix=/usr/local/sphinx2 --with-mysql=/usr/local/mariadb/ [root@MevHost sphinxb] # make && make install |
-
安裝
sphinx
客戶端
這個要安裝上,不然安裝PHP安裝sphinx擴展時會出現報錯
1
2
3
|
[root@MevHost sphinxb] # cd /usr/local/src/sphinx/sphinx-2.2.11-release/api/libsphinxclient //sphinx-2.2.11-release目錄下 [root@MevHost sphinxb] # ./configure --prefix=/usr/local/sphinx2/libsphinxclient [root@MevHost sphinxb] # make && make install |
-
為PHP安裝
sphinx
擴展
1
2
3
4
5
6
|
[root@MevHost sphinxb] # cd /usr/local/src/sphinx [root@MevHost sphinxb] # tar zxvf sphinx-1.3.1.tgz [root@MevHost sphinxb] # cd sphinx-1.3.1 [root@MevHost sphinxb] # phpize [root@MevHost sphinxb] # ./configure --with-sphinx=/usr/local/sphinx2/libsphinxclient --with-php-config=/usr/local/php/bin/php-config [root@MevHost sphinxb] # make && make install |
成功后再 php.ini 添加:
1
|
extension=sphinx.so |
PHP7版本sphinx擴展下載
下載地址
http://git.php.net/?p=pecl/search_engine/sphinx.git;a=shortlog;h=refs/heads/php7
- 安裝scws
1
2
3
4
5
|
[root@MevHost sphinxb] # tar -jxvf scws-1.2.3.tar.bz2 [root@MevHost sphinxb] # mkdir /usr/local/scws [root@MevHost sphinxb] # cd scws-1.2.3 [root@MevHost sphinxb] # ./configure --prefix=/usr/local/scws/ [root@MevHost sphinxb] # make && make install |
- 為PHP安裝scws擴展
1
2
3
4
|
[root@MevHost sphinxb] # cd /usr/local/src/sphinx/scws-1.2.3/phpext [root@MevHost sphinxb] # phpize [root@MevHost sphinxb] # ./configure --with-php-config=/usr/local/php/bin/php-config [root@MevHost sphinxb] # make && make install |
在php.ini 加入
1
2
3
|
extension = scws.so scws.default.charset=utf-8 scws.default.fpath = /usr/local/scws/etc |
- 安裝scws詞庫
1
2
3
|
[root@MevHost sphinxb] # tar jxvf scws-dict-chs-utf8.tar.bz2 -C /usr/local/scws/etc/ #www為php-fpm運行用戶 [root@MevHost sphinxb] # chown www:www /usr/local/scws/etc/dict.utf8.xdb |
創建MySQL數據源
mtest.sql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
/* Navicat MySQL Data Transfer Source Database : mtest Target Server Type : MYSQL Target Server Version : 50505 File Encoding : 65001 Date : 2017-12-10 17:47:58 */ SET FOREIGN_KEY_CHECKS=0; -- ---------------------------- -- Table structure for userinfo -- ---------------------------- DROP TABLE IF EXISTS `userinfo`; CREATE TABLE `userinfo` ( `id` int (11) unsigned NOT NULL AUTO_INCREMENT, `userid` int (11) unsigned NOT NULL DEFAULT '0' , `addtime` datetime NOT NULL , `post` varchar (20) NOT NULL DEFAULT '' , `summary` text NOT NULL , PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of userinfo -- ---------------------------- INSERT INTO `userinfo` VALUES ( '17' , '1' , '2017-12-10 00:24:54' , '在CentOS7中使用Sendmail通' , 'sendmail' ); INSERT INTO `userinfo` VALUES ( '18' , '2' , '2017-12-10 10:24:54' , '徹底理解PHP的SESSION機制' , 'session' ); INSERT INTO `userinfo` VALUES ( '19' , '3' , '2017-12-10 12:24:54' , '手把手編寫自己的PHPMVC框架實例教程' , 'mvc' ); INSERT INTO `userinfo` VALUES ( '20' , '4' , '2017-12-10 00:24:54' , 'php獲取今日、昨日、上周、本月的起始時' , '時間' ); -- ---------------------------- -- Table structure for users -- ---------------------------- DROP TABLE IF EXISTS `users`; CREATE TABLE `users` ( `id` int (11) unsigned NOT NULL AUTO_INCREMENT, `username` varchar (20) NOT NULL DEFAULT '' , PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of users -- ---------------------------- INSERT INTO `users` VALUES ( '1' , 'Lionee' ); INSERT INTO `users` VALUES ( '2' , 'libber' ); INSERT INTO `users` VALUES ( '3' , 'sysmob' ); INSERT INTO `users` VALUES ( '4' , '學習' ); |
配置sphinx
配置文件在/usr/local/sphinx2/etc
1
|
cp sphinx-min.conf.dist sphinx.conf |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
|
source users { type = mysql sql_host = 127.0.0.1 sql_user = root sql_pass = 123456 sql_db = mtest sql_port = 3306 # optional, default is 3306 sql_query_pre = SET NAMES utf8 sql_query_pre = SET SESSION query_cache_type=OFF sql_query = SELECT a. id , a.userid,b.username, UNIX_TIMESTAMP(a.addtime) AS addtime, a.post, a.summary FROM userinfo a left join users b on a.userid = b. id sql_attr_uint = userid sql_field_string = username sql_field_string = post sql_attr_timestamp = addtime sql_ranged_throttle = 0 #sql_attr_uint = group_id #sql_attr_timestamp = date_added #sql_ranged_throttle = 0 } source src1throttled : users { sql_ranged_throttle = 100 } index users { source = users path = /usr/local/sphinx2/var/data/users docinfo = extern mlock = 0 morphology = none min_word_len = 1 html_strip = 1 charset_table = U+FF10..U+FF19->0..9, 0..9, U+FF41..U+FF5A->a..z, U+FF21..U+FF3A->a..z,A..Z->a..z, a..z, U+0149, U+017F, U+0138, U+00DF, U+00FF, U+00C0..U+00D6->U+00E0..U+00F6,U+00E0..U+00F6, U+00D8..U+00DE->U+00F8..U+00FE, U+00F8..U+00FE, U+0100->U+0101, U+0101,U+0102->U+0103, U+0103, U+0104->U+0105, U+0105, U+0106->U+0107, U+0107, U+0108->U+0109,U+0109, U+010A->U+010B, U+010B, U+010C->U+010D, U+010D, U+010E->U+010F, U+010F,U+0110->U+0111, U+0111, U+0112->U+0113, U+0113, U+0114->U+0115, U+0115, U+0116->U+0117,U+0117, U+0118->U+0119, U+0119, U+011A->U+011B, U+011B, U+011C->U+011D, U+011D,U+011E->U+011F, U+011F, U+0130->U+0131, U+0131, U+0132->U+0133, U+0133, U+0134->U+0135,U+0135, U+0136->U+0137, U+0137, U+0139->U+013A, U+013A, U+013B->U+013C, U+013C,U+013D->U+013E, U+013E, U+013F->U+0140, U+0140, U+0141->U+0142, U+0142, U+0143->U+0144,U+0144, U+0145->U+0146, U+0146, U+0147->U+0148, U+0148, U+014A->U+014B, U+014B,U+014C->U+014D, U+014D, U+014E->U+014F, U+014F, U+0150->U+0151, U+0151, U+0152->U+0153,U+0153, U+0154->U+0155, U+0155, U+0156->U+0157, U+0157, U+0158->U+0159, U+0159,U+015A->U+015B, U+015B, U+015C->U+015D, U+015D, U+015E->U+015F, U+015F, U+0160->U+0161,U+0161, U+0162->U+0163, U+0163, U+0164->U+0165, U+0165, U+0166->U+0167, U+0167,U+0168->U+0169, U+0169, U+016A->U+016B, U+016B, U+016C->U+016D, U+016D, U+016E->U+016F,U+016F, U+0170->U+0171, U+0171, U+0172->U+0173, U+0173, U+0174->U+0175, U+0175,U+0176->U+0177, U+0177, U+0178->U+00FF, U+00FF, U+0179->U+017A, U+017A, U+017B->U+017C,U+017C, U+017D->U+017E, U+017E, U+0410..U+042F->U+0430..U+044F, U+0430..U+044F,U+05D0..U+05EA, U+0531..U+0556->U+0561..U+0586, U+0561..U+0587, U+0621..U+063A, U+01B9,U+01BF, U+0640..U+064A, U+0660..U+0669, U+066E, U+066F, U+0671..U+06D3, U+06F0..U+06FF,U+0904..U+0939, U+0958..U+095F, U+0960..U+0963, U+0966..U+096F, U+097B..U+097F,U+0985..U+09B9, U+09CE, U+09DC..U+09E3, U+09E6..U+09EF, U+0A05..U+0A39, U+0A59..U+0A5E,U+0A66..U+0A6F, U+0A85..U+0AB9, U+0AE0..U+0AE3, U+0AE6..U+0AEF, U+0B05..U+0B39,U+0B5C..U+0B61, U+0B66..U+0B6F, U+0B71, U+0B85..U+0BB9, U+0BE6..U+0BF2, U+0C05..U+0C39,U+0C66..U+0C6F, U+0C85..U+0CB9, U+0CDE..U+0CE3, U+0CE6..U+0CEF, U+0D05..U+0D39, U+0D60,U+0D61, U+0D66..U+0D6F, U+0D85..U+0DC6, U+1900..U+1938, U+1946..U+194F, U+A800..U+A805,U+A807..U+A822, U+0386->U+03B1, U+03AC->U+03B1, U+0388->U+03B5, U+03AD->U+03B5,U+0389->U+03B7, U+03AE->U+03B7, U+038A->U+03B9, U+0390->U+03B9, U+03AA->U+03B9,U+03AF->U+03B9, U+03CA->U+03B9, U+038C->U+03BF, U+03CC->U+03BF, U+038E->U+03C5,U+03AB->U+03C5, U+03B0->U+03C5, U+03CB->U+03C5, U+03CD->U+03C5, U+038F->U+03C9,U+03CE->U+03C9, U+03C2->U+03C3, U+0391..U+03A1->U+03B1..U+03C1,U+03A3..U+03A9->U+03C3..U+03C9, U+03B1..U+03C1, U+03C3..U+03C9, U+0E01..U+0E2E,U+0E30..U+0E3A, U+0E40..U+0E45, U+0E47, U+0E50..U+0E59, U+A000..U+A48F, U+4E00..U+9FBF,U+3400..U+4DBF, U+20000..U+2A6DF, U+F900..U+FAFF, U+2F800..U+2FA1F, U+2E80..U+2EFF,U+2F00..U+2FDF, U+3100..U+312F, U+31A0..U+31BF, U+3040..U+309F, U+30A0..U+30FF,U+31F0..U+31FF, U+AC00..U+D7AF, U+1100..U+11FF, U+3130..U+318F, U+A000..U+A48F,U+A490..U+A4CF ngram_len = 1 ngram_chars = U+4E00..U+9FBF, U+3400..U+4DBF, U+20000..U+2A6DF, U+F900..U+FAFF,U+2F800..U+2FA1F, U+2E80..U+2EFF, U+2F00..U+2FDF, U+3100..U+312F, U+31A0..U+31BF,U+3040..U+309F, U+30A0..U+30FF,U+31F0..U+31FF, U+AC00..U+D7AF, U+1100..U+11FF,U+3130..U+318F, U+A000..U+A48F, U+A490..U+A4CF } common { } indexer { mem_limit = 128M } searchd { #php listen = 9312 #mysql listen = 9306:mysql41 log = /usr/local/sphinx2/var/log/searchd .log query_log = /usr/local/sphinx2/var/log/query .log query_log_format = sphinxql read_timeout = 5 client_timeout = 300 max_children = 30 persistent_connections_limit = 30 pid_file = /usr/local/sphinx2/var/log/searchd .pid seamless_rotate = 1 preopen_indexes = 1 unlink_old = 1 mva_updates_pool = 1M max_packet_size = 8M max_filters = 256 max_filter_values = 4096 max_batch_queries = 32 workers = threads # for RT to work } |
啟動sphinx
1
2
3
|
[root@MevHost ~] # pkill searchd [root@MevHost ~] # /usr/local/sphinx2/bin/indexer --config /usr/local/sphinx2/etc/sphinx.conf --all [root@MevHost ~] # /usr/local/sphinx2/bin/searchd --config /usr/local/sphinx2/etc/sphinx.conf |
如果出現下面的報錯
"Oops! It seems that sphinx was built with wrong endianess (cross-compiling?)
either reconfigure and rebuild, defining ac_cv_c_bigendian=no in the environment of
./configure script,
either ensure that '#define USE_LITTLE_ENDIAN = 1' in config/config.h"
我是直接把sphinx下面的config/config.h 改成了他提示的這個 #define USE_LITTLE_ENDIAN = 1,之后make的,
接下來的這段是我們的PHP代碼了
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
|
<!DOCTYPE html> <html lang= "en" > <head> <meta charset= "UTF-8" > <title>Document</title> </head> <body> <form method= "post" action= 'test.php' > <p>輸入:</p> <input type= "text" name= "q" autocomplete= "false" > </form> </body> </html> <?php // phpinfo();die; ini_set ( 'display_errors' , '1' ); error_reporting (E_ALL); header( "Content-type: text/html; charset=utf-8" ); if ( $_POST ){ $b_time = microtime(true); $key = $_POST [ 'q' ]; $index = "users" ; //========================================分詞 $so = scws_new(); $so ->set_charset( 'utf-8' ); //默認詞庫 $so ->add_dict( ini_get ( 'scws.default.fpath' ) . '/dict.utf8.xdb' ); //自定義詞庫 // $so->add_dict('./dd.txt',SCWS_XDICT_TXT); //默認規則 $so ->set_rule( ini_get ( 'scws.default.fpath' ) . '/rules.utf8.ini' ); //設定分詞返回結果時是否去除一些特殊的標點符號 $so ->set_ignore(true); //設定分詞返回結果時是否復式分割,如“中國人”返回“中國+人+中國人”三個詞。 // 按位異或的 1 | 2 | 4 | 8 分別表示: 短詞 | 二元 | 主要單字 | 所有單字 //1,2,4,8 分別對應常量 SCWS_MULTI_SHORT SCWS_MULTI_DUALITY SCWS_MULTI_ZMAIN SCWS_MULTI_ZALL $so ->set_multi(false); //設定是否將閑散文字自動以二字分詞法聚合 $so ->set_duality(false); //設定搜索詞 $so ->send_text( $key ); $words_array = $so ->get_result(); $words = "" ; foreach ( $words_array as $v ) { $words = $words . '|(' . $v [ 'word' ]. ')' ; } //加入全詞 # $words = '(' . $key . ')' . $words ; $words = trim( $words , '|' ); $so ->close(); echo '<p>輸入:' . $key . '</p>' . "\r\n" ; echo '<p>分詞:' . $words . '</p>' . "\r\n" ; //========================================搜索 $sc = new SphinxClient(); $sc ->SetServer( '127.0.0.1' ,9312); # $sc ->SetMatchMode(SPH_MATCH_ALL); $sc ->SetMatchMode(SPH_MATCH_ANY); $sc ->SetArrayResult(TRUE); $res = $sc ->Query( $words , $index ); echo "<hr>" ; echo "<pre>" ; print_r( $res ); $e_time = microtime(true); $time = $e_time - $b_time ; echo $time ; } exit ; ?> |
sphinx 配置文件解析
- source:數據源,數據是從什么地方來的。
- index:索引,當有數據源之后,從數據源處構建索引。索引實際上就是相當于一個字典檢索。有了整本字典內容以后,才會有字典檢索。
- searchd:提供搜索查詢服務。它一般是以deamon的形式運行在后臺的。
- indexer:構建索引的服務。當要重新構建索引的時候,就是調用indexer這個命令。
- attr:屬性,屬性是存在索引中的,它不進行全文索引,但是可以用于過濾和排序。
sphinx.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
|
## 數據源src1 source src1 { ## 說明數據源的類型。數據源的類型可以是:mysql,pgsql,mssql,xmlpipe,odbc,python ## 有人會奇怪,python是一種語言怎么可以成為數據源呢? ## python作為一種語言,可以操作任意其他的數據來源來獲取數據,更多數據請看:(http://www.coreseek.cn/products-install/python/) type = mysql ## 下面是sql數據庫特有的端口,用戶名,密碼,數據庫名等。 sql_host = localhost sql_user = test sql_pass = sql_db = test sql_port = 3306 ## 如果是使用unix sock連接可以使用這個。 # sql_sock = /tmp/mysql.sock ## indexer和mysql之間的交互,需要考慮到效率和安全性。 ## 比如考慮到效率,他們兩者之間的交互需要使用壓縮協議;考慮到安全,他們兩者之間的傳輸需要使用ssl ## 那么這個參數就代表這個意思,0/32/2048/32768 無/使用壓縮協議/握手后切換到ssl/Mysql 4.1版本身份認證。 # mysql_connect_flags = 32 ## 當mysql_connect_flags設置為2048(ssl)的時候,下面幾個就代表ssl連接所需要使用的幾個參數。 # mysql_ssl_cert = /etc/ssl/client-cert.pem # mysql_ssl_key = /etc/ssl/client-key.pem # mysql_ssl_ca = /etc/ssl/cacert.pem ## mssql特有,是否使用windows登陸 # mssql_winauth = 1 ## mssql特有,是使用unicode還是單字節數據。 # mssql_unicode = 1 # request Unicode data from server ## odbc的dsn串 # odbc_dsn = DBQ=C:\data;DefaultDir=C:\data;Driver={Microsoft Text Driver (*.txt; *.csv)}; ## sql某一列的緩沖大小,一般是針對字符串來說的。 ## 為什么要有這么一種緩沖呢? ## 有的字符串,雖然長度很長,但是實際上并沒有使用那么長的字符,所以在Sphinx并不會收錄所有的字符,而是給每個屬性一個緩存作為長度限制。 ## 默認情況下非字符類型的屬性是1KB,字符類型的屬性是1MB。 ## 而如果想要配置這個buffer的話,就可以在這里進行配置了。 # sql_column_buffers = content=12M, comments=1M ## indexer的sql執行前需要執行的操作。 # sql_query_pre = SET NAMES utf8 # sql_query_pre = SET SESSION query_cache_type=OFF ## indexer的sql執行語句 sql_query = \ SELECT id , group_id, UNIX_TIMESTAMP(date_added) AS date_added, title, content \ FROM documents ## 有的時候有多個表,我們想要查詢的字段在其他表中。這個時候就需要對sql_query進行join操作。 ## 而這個join操作可能非常慢,導致建立索引的時候特別慢,那么這個時候,就可以考慮在sphinx端進行join操作了。 ## sql_joined_field是增加一個字段,這個字段是從其他表查詢中查詢出來的。 ## 這里封號后面的查詢語句是有要求的,如果是query,則返回id和查詢字段,如果是payload-query,則返回id,查詢字段和權重。 ## 并且這里的后一個查詢需要按照id進行升序排列。 # sql_joined_field = tags from query; SELECT docid, CONCAT('tag',tagid) FROM tags ORDER BY docid ASC # sql_joined_field = wtags from payload-query; SELECT docid, tag, tagweight FROM tags ORDER BY docid ASC ## 外部文件字段,意思就是一個表中,有一個字段存的是外部文件地址,但是實際的字段內容在文件中。比如這個字段叫做content_file_path。 ## 當indexer建立索引的時候,查到這個字段,就讀取這個文件地址,然后加載,并進行分詞和索引建立等操作。 # sql_file_field = content_file_path ## 當數據源數據太大的時候,一個sql語句查詢下來往往很有可能鎖表等操作。 ## 那么我么就可以使用多次查詢,那么這個多次查詢就需要有個范圍和步長,sql_query_range和sql_range_step就是做這個使用的。 ## 獲取最大和最小的id,然后根據步長來獲取數據。比如下面的例子,如果有4500條數據,這個表建立索引的時候就會進行5次sql查詢。 ## 而5次sql查詢每次的間隔時間是使用sql_ranged_rhrottle來進行設置的。單位是毫秒。 # sql_query_range = SELECT MIN(id),MAX(id) FROM documents # sql_range_step = 1000 # sql_ranged_throttle = 0 ## 下面都是些不同屬性的數據了 ## 先要了解屬性的概念:屬性是存在索引中的,它不進行全文索引,但是可以用于過濾和排序。 ## uint無符號整型屬性 sql_attr_uint = group_id ## bool屬性 # sql_attr_bool = is_deleted ## 長整型屬性 # sql_attr_bigint = my_bigint_id ## 時間戳屬性,經常被用于做排序 sql_attr_timestamp = date_added ## 字符串排序屬性。一般我們按照字符串排序的話,我們會將這個字符串存下來進入到索引中,然后在查詢的時候比較索引中得字符大小進行排序。 ## 但是這個時候索引就會很大,于是我們就想到了一個方法,我們在建立索引的時候,先將字符串值從數據庫中取出,暫存,排序。 ## 然后給排序后的數組分配一個序號,然后在建立索引的時候,就將這個序號存入到索引中去。這樣在查詢的時候也就能完成字符串排序的操作。 ## 這,就是這個字段的意義。 # sql_attr_str2ordinal = author_name ## 浮點數屬性,經常在查詢地理經緯度的時候會用到。 # sql_attr_float = lat_radians # sql_attr_float = long_radians ## 多值屬性(MVA) ## 試想一下,有一個文章系統,每篇文章都有多個標簽,這個文章就叫做多值屬性。 ## 我要對某個標簽進行查詢過濾,那么在建立查詢的時候就應該把這個標簽的值放入到索引中。 ## 這個字段,sql_attr_multi就是用來做這個事情的。 # sql_attr_multi = uint tag from query; SELECT docid, tagid FROM tags # sql_attr_multi = uint tag from ranged-query; \ # SELECT docid, tagid FROM tags WHERE id>=$start AND id<=$end; \ # SELECT MIN(docid), MAX(docid) FROM tags ## 字符串屬性。 # sql_attr_string = stitle ## 文檔詞匯數記錄屬性。比如下面就是在索引建立的時候增加一個詞匯數的字段 # sql_attr_str2wordcount = stitle ## 字符串字段,可全文搜索,可返回原始文本信息。 # sql_field_string = author ## 文檔詞匯數記錄字段,可全文搜索,可返回原始信息 # sql_field_str2wordcount = title ## 取后查詢,在sql_query執行后立即操作。 ## 它和sql_query_post_index的區別就是執行時間不同 ## sql_query_post是在sql_query執行后執行,而sql_query_post_index是在索引建立完成后才執行。 ## 所以如果要記錄最后索引執行時間,那么應該在sql_query_post_index中執行。 # sql_query_post = ## 參考sql_query_post的說明。 # sql_query_post_index = REPLACE INTO counters ( id, val ) \ # VALUES ( 'max_indexed_id', $maxid ) ## 命令行獲取信息查詢。 ## 什么意思呢? ## 我們進行索引一般只會返回主鍵id,而不會返回表中的所有字段。 ## 但是在調試的時候,我們一般需要返回表中的字段,那這個時候,就需要使用sql_query_info。 ## 同時這個字段只在控制臺有效,在api中是無效的。 sql_query_info = SELECT * FROM documents WHERE id =$ id ## 比如有兩個索引,一個索引比較舊,一個索引比較新,那么舊索引中就會有數據是舊的。 ## 當我要對兩個索引進行搜索的時候,哪些數據要按照新的索引來進行查詢呢。 ## 這個時候就使用到了這個字段了。 ## 這里的例子(http://www.coreseek.cn/docs/coreseek_4.1-sphinx_2.0.1-beta.html#conf-sql-query-killlist)給的非常清晰了。 # sql_query_killlist = SELECT id FROM documents WHERE edited>=@last_reindex ## 下面幾個壓縮解壓的配置都是為了一個目的:讓索引重建的時候不要影響數據庫的性能表現。 ## SQL數據源解壓字段設置 # unpack_zlib = zlib_column ## MySQL數據源解壓字段設置 # unpack_mysqlcompress = compressed_column # unpack_mysqlcompress = compressed_column_2 ## MySQL數據源解壓緩沖區設置 # unpack_mysqlcompress_maxsize = 16M ## xmlpipe的數據源就是一個xml文檔 # type = xmlpipe ## 讀取數據源的命令 # xmlpipe_command = cat /home/yejianfeng/instance/coreseek/var/test.xml ## 字段 # xmlpipe_field = subject # xmlpipe_field = content ## 屬性 # xmlpipe_attr_timestamp = published # xmlpipe_attr_uint = author_id ## UTF-8修復設置 ## 只適用xmlpipe2數據源,數據源中有可能有非utf-8的字符,這個時候解析就有可能出現問題 ## 如果設置了這個字段,非utf-8序列就會全部被替換為空格。 # xmlpipe_fixup_utf8 = 1 } ## sphinx的source是有繼承這么一種屬性的,意思就是除了父source之外,這個source還有這個特性 source src1throttled : src1 { sql_ranged_throttle = 100 } ## 索引test1 index test1 { ## 索引類型,包括有plain,distributed和rt。分別是普通索引/分布式索引/增量索引。默認是plain。 # type = plain ## 索引數據源 source = src1 ## 索引文件存放路徑 path = /home/yejianfeng/instance/coreseek/var/data/test1 ## 文檔信息的存儲模式,包括有none,extern,inline。默認是extern。 ## docinfo指的就是數據的所有屬性(field)構成的一個集合。 ## 首先文檔id是存儲在一個文件中的(spa) ## 當使用inline的時候,文檔的屬性和文件的id都是存放在spa中的,所以進行查詢過濾的時候,不需要進行額外操作。 ## 當使用extern的時候,文檔的屬性是存放在另外一個文件(spd)中的,但是當啟動searchd的時候,會把這個文件加載到內存中。 ## extern就意味著每次做查詢過濾的時候,除了查找文檔id之外,還需要去內存中根據屬性進行過濾。 ## 但是即使這樣,extern由于文件大小小,效率也不低。所以不是有特殊要求,一般都是使用extern docinfo = extern ## 緩沖內存鎖定。 ## searchd會講spa和spi預讀取到內存中。但是如果這部分內存數據長時間沒有訪問,則它會被交換到磁盤上。 ## 設置了mlock就不會出現這個問題,這部分數據會一直存放在內存中的。 mlock = 0 ## 詞形處理器 ## 詞形處理是什么意思呢?比如在英語中,dogs是dog的復數,所以dog是dogs的詞干,這兩個實際上是同一個詞。 ## 所以英語的詞形處理器會講dogs當做dog來進行處理。 morphology = none ## 詞形處理有的時候會有問題,比如將gps處理成gp,這個設置可以允許根據詞的長度來決定是否要使用詞形處理器。 # min_stemming_len = 1 ## 詞形處理后是否還要檢索原詞? # index_exact_words = 1 ## 停止詞,停止詞是不被索引的詞。 # stopwords = /home/yejianfeng/instance/coreseek/var/data/stopwords.txt ## 自定義詞形字典 # wordforms = /home/yejianfeng/instance/coreseek/var/data/wordforms.txt ## 詞匯特殊處理。 ## 有的一些特殊詞我們希望把它當成另外一個詞來處理。比如,c++ => cplusplus來處理。 # exceptions = /home/yejianfeng/instance/coreseek/var/data/exceptions.txt ## 最小索引詞長度,小于這個長度的詞不會被索引。 min_word_len = 1 ## 字符集編碼類型,可以為sbcs,utf-8。對于Coreseek,還可以有zh_cn.utf-8,zh_ch.gbk,zh_ch.big5 charset_type = sbcs ## 字符表和大小寫轉換規則。對于Coreseek,這個字段無效。 # 'sbcs' default value is # charset_table = 0..9, A..Z->a..z, _, a..z, U+A8->U+B8, U+B8, U+C0..U+DF->U+E0..U+FF, U+E0..U+FF # # 'utf-8' default value is # charset_table = 0..9, A..Z->a..z, _, a..z, U+410..U+42F->U+430..U+44F, U+430..U+44F ## 忽略字符表。在忽略字符表中的前后詞會被連起來當做一個單獨關鍵詞處理。 # ignore_chars = U+00AD ## 是否啟用通配符,默認為0,不啟用 # enable_star = 1 ## min_prefix_len,min_infix_len,prefix_fields,infix_fields都是在enable_star開啟的時候才有效果。 ## 最小前綴索引長度 ## 為什么要有這個配置項呢? ## 首先這個是當啟用通配符配置啟用的前提下說的,前綴索引使得一個關鍵詞產生了多個索引項,導致索引文件體積和搜索時間增加巨大。 ## 那么我們就有必要限制下前綴索引的前綴長度,比如example,當前綴索引長度設置為5的時候,它只會分解為exampl,example了。 # min_prefix_len = 0 ## 最小索引中綴長度。理解同上。 # min_infix_len = 0 ## 前綴索引和中綴索引字段列表。并不是所有的字段都需要進行前綴和中綴索引。 # prefix_fields = filename # infix_fields = url, domain ## 詞匯展開 ## 是否盡可能展開關鍵字的精確格式或者型號形式 # expand_keywords = 1 ## N-Gram索引的分詞技術 ## N-Gram是指不按照詞典,而是按照字長來分詞,這個主要是針對非英文體系的一些語言來做的(中文、韓文、日文) ## 對coreseek來說,這兩個配置項可以忽略。 # ngram_len = 1 # ngram_chars = U+3000..U+2FA1F ## 詞組邊界符列表和步長 ## 哪些字符被看做分隔不同詞組的邊界。 # phrase_boundary = ., ?, !, U+2026 # horizontal ellipsis # phrase_boundary_step = 100 ## 混合字符列表 # blend_chars = +, &, U+23 # blend_mode = trim_tail, skip_pure ## html標記清理,是否從輸出全文數據中去除HTML標記。 html_strip = 0 ## HTML標記屬性索引設置。 # html_index_attrs = img=alt,title; a=title; ## 需要清理的html元素 # html_remove_elements = style, script ## searchd是預先打開全部索引還是每次查詢再打開索引。 # preopen = 1 ## 字典文件是保持在磁盤上還是將他預先緩沖在內存中。 # ondisk_dict = 1 ## 由于在索引建立的時候,需要建立臨時文件和和副本,還有舊的索引 ## 這個時候磁盤使用量會暴增,于是有個方法是臨時文件重復利用 ## 這個配置會極大減少建立索引時候的磁盤壓力,代價是索引建立速度變慢。 # inplace_enable = 1 # inplace_hit_gap = 0 # preallocated hitlist gap size # inplace_docinfo_gap = 0 # preallocated docinfo gap size # inplace_reloc_factor = 0.1 # relocation buffer size within arena # inplace_write_factor = 0.1 # write buffer size within arena ## 在經過過短的位置后增加位置值 # overshort_step = 1 ## 在經過 停用詞 處后增加位置值 # stopword_step = 1 ## 位置忽略詞匯列表 # hitless_words = all # hitless_words = hitless.txt ## 是否檢測并索引句子和段落邊界 # index_sp = 1 ## 字段內需要索引的HTML/XML區域的標簽列表 # index_zones = title, h*, th } index test1stemmed : test1 { path = /home/yejianfeng/instance/coreseek/var/data/test1stemmed morphology = stem_en } index dist1 { type = distributed local = test1 local = test1stemmed ## 分布式索引(distributed index)中的遠程代理和索引聲明 agent = localhost:9313:remote1 agent = localhost:9314:remote2,remote3 # agent = /var/run/searchd.sock:remote4 ## 分布式索引( distributed index)中聲明遠程黑洞代理 # agent_blackhole = testbox:9312:testindex1,testindex2 ## 遠程代理的連接超時時間 agent_connect_timeout = 1000 ## 遠程查詢超時時間 agent_query_timeout = 3000 } index rt { type = rt path = /home/yejianfeng/instance/coreseek/var/data/rt ## RT索引內存限制 # rt_mem_limit = 512M ## 全文字段定義 rt_field = title rt_field = content ## 無符號整數屬性定義 rt_attr_uint = gid ## 各種屬性定義 # rt_attr_bigint = guid # rt_attr_float = gpa # rt_attr_timestamp = ts_added # rt_attr_string = author } indexer { ## 建立索引的時候,索引內存限制 mem_limit = 32M ## 每秒最大I/O操作次數,用于限制I/O操作 # max_iops = 40 ## 最大允許的I/O操作大小,以字節為單位,用于I/O節流 # max_iosize = 1048576 ## 對于XMLLpipe2數據源允許的最大的字段大小,以字節為單位 # max_xmlpipe2_field = 4M ## 寫緩沖區的大小,單位是字節 # write_buffer = 1M ## 文件字段可用的最大緩沖區大小,字節為單位 # max_file_field_buffer = 32M } ## 搜索服務配置 searchd { # listen = 127.0.0.1 # listen = 192.168.0.1:9312 # listen = 9312 # listen = /var/run/searchd.sock ## 監聽端口 listen = 9312 listen = 9306:mysql41 ## 監聽日志 log = /home/yejianfeng/instance/coreseek/var/log/searchd .log ## 查詢日志 query_log = /home/yejianfeng/instance/coreseek/var/log/query .log ## 客戶端讀超時時間 read_timeout = 5 ## 客戶端持久連接超時時間,即客戶端讀一次以后,持久連接,然后再讀一次。中間這個持久連接的時間。 client_timeout = 300 ## 并行執行搜索的數目 max_children = 30 ## 進程id文件 pid_file = /home/yejianfeng/instance/coreseek/var/log/searchd .pid ## 守護進程在內存中為每個索引所保持并返回給客戶端的匹配數目的最大值 max_matches = 1000 ## 無縫輪轉。防止 searchd 輪換在需要預取大量數據的索引時停止響應 ## 當進行索引輪換的時候,可能需要消耗大量的時間在輪換索引上。 ## 但是啟動了無縫輪轉,就以消耗內存為代價減少輪轉的時間 seamless_rotate = 1 ## 索引預開啟,是否強制重新打開所有索引文件 preopen_indexes = 1 ## 索引輪換成功之后,是否刪除以.old為擴展名的索引拷貝 unlink_old = 1 ## 屬性刷新周期 ## 就是使用UpdateAttributes()更新的文檔屬性每隔多少時間寫回到磁盤中。 # attr_flush_period = 900 ## 索引字典存儲方式 # ondisk_dict_default = 1 ## 用于多值屬性MVA更新的存儲空間的內存共享池大小 mva_updates_pool = 1M ## 網絡通訊時允許的最大的包的大小 max_packet_size = 8M ## 崩潰日志文件 # crash_log_path = /home/yejianfeng/instance/coreseek/var/log/crash ## 每次查詢允許設置的過濾器的最大個數 max_filters = 256 ## 單個過濾器允許的值的最大個數 max_filter_values = 4096 ## TCP監聽待處理隊列長度 # listen_backlog = 5 ## 每個關鍵字的讀緩沖區的大小 # read_buffer = 256K ## 無匹配時讀操作的大小 # read_unhinted = 32K ## 每次批量查詢的查詢數限制 max_batch_queries = 32 ## 每個查詢的公共子樹文檔緩存大小 # subtree_docs_cache = 4M ## 每個查詢的公共子樹命中緩存大小 # subtree_hits_cache = 8M ## 多處理模式(MPM)。 可選項;可用值為none、fork、prefork,以及threads。 默認在Unix類系統為form,Windows系統為threads。 workers = threads # for RT to work ## 并發查詢線程數 # dist_threads = 4 ## 二進制日志路徑 # binlog_path = # disable logging # binlog_path = /home/yejianfeng/instance/coreseek/var/data # binlog.001 etc will be created there ## 二進制日志刷新 # binlog_flush = 2 ## 二進制日志大小限制 # binlog_max_log_size = 256M ## 線程堆棧 # thread_stack = 128K ## 關鍵字展開限制 # expansion_limit = 1000 ## RT索引刷新周期 # rt_flush_period = 900 ## 查詢日志格式 ## 可選項,可用值為plain、sphinxql,默認為plain。 # query_log_format = sphinxql ## MySQL版本設置 # mysql_version_string = 5.0.37 ## 插件目錄 # plugin_dir = /usr/local/sphinx/lib ## 服務端默認字符集 # collation_server = utf8_general_ci ## 服務端libc字符集 # collation_libc_locale = ru_RU.UTF-8 ## 線程服務看守 # watchdog = 1 ## 兼容模式 # compat_sphinxql_magics = 1 } |
希望本文所述對大家PHP程序設計有所幫助。
原文鏈接:https://blog.csdn.net/l534148647/article/details/78766260