你為什麼需要搜索引擎?單純數據庫不夠用?如果你只是創建小網站,數據庫就夠了。但當你創建中性或大型應用的時候,搜索引擎是更明智的選擇。當然如是一說,小網站也可以利用Solr,獲得高相關性的搜索結果。
想象一下你在寫一個電子商務網站的搜索查詢程序。最直接的想法就是如下的數據庫查詢語句:
1
SELECT
*
FROM
PRODUCTS
2
WHERE
LOWER
(title)
like
LOWER
(
'%$phrase%'
)
3
OR
LOWER
(description)
like
LOWER
(
'%$phrase%'
);
查詢標題或描述中的短語時,它工作正常。但是現實事物很復雜,比如說Apple iPhone 4G black 16GB(蘋果4G網絡iPhone黑色16GB)。搜索“iPhone 16G”的時候,就沒結果。你可以用%替換空格應付這種情況。
1
$phrase
=
str_replace
(
' '
,
'%'
,
$phrase
);
那麼查詢“iPhone 16GB 4G”的時候呢?顯然詞序改變了,它又無法正常工作。我猜你又會添加一個字段保存詞序。那麼寫錯詞怎麼辦?同義詞怎麼辦?為如此的搜索系統想一個好的解決方案很有挑戰性。
設計一個精妙的算法不是解決這類問題的關鍵. 文本的搜素是需要消耗資源的. 將太多的壓力放在數據庫端永遠不是一個好辦法. 原因是數據庫不能很方便的擴展. 你不能像web server 或者 Memcached一樣,簡單的增加一個實例.擴展數據庫需要一些准備, 代碼的修改, 配置, down機維護時間, 總之成本是非常昂貴的. 好消息是Solr就是專門解決這類問題的.
Solr是一個基於Apache Lucene的企業級搜索平台. 快,穩定, 有很好的文檔當然擴展起來也很方便. 由於Solr是有個強大的解決方案, 他的所有特性就不在這篇文章裡面一一列舉了. 這家伙上收起來也是相當easy哦.
首先從官方網站下載最新的版本。Solr是一個由Java語言編寫的應用程序,你需要Java Runtime環境才可以運行。
1
$
cd
solr-4.1.0/example/
2
$ java -jar start.jar
大概幾秒鐘後你就可以看到下面的信息:
1
2013-03-09 18:47:41.177:INFO:oejs.AbstractConnector:Started [email protected]:8983
Solr有一個web界面,工作在8983端口下,打開浏覽器訪問http://localhost:8983/solr/.
在左手邊的導航區你會找到“collection1″。在Solr中,Collections類似於數據庫的表,你可以查詢數據。點擊一個collection,選擇她的子菜單 “query”。
第一個選項叫 “Request-Handler (qt)”,擁有默認值 “/select”。Request handlers是一組預定義查詢. 如果你查看Solr config文件,你就會看到是這樣的:
1
$ vim solr-4.1.0/example/solr/collection1/conf/solrconfig.xml
1
<
requestHandler
name
=
"/select"
class
=
"solr.SearchHandler"
>
2
<
lst
name
=
"defaults"
>
3
<
str
name
=
"echoParams"
>explicit</
str
>
4
<
int
name
=
"rows"
>10</
int
>
5
<
str
name
=
"df"
>text</
str
>
6
</
lst
>
7
</
requestHandler
>
第二個參數才是我們最感興趣的。默認值 “*:*” 意味著查詢任何內容,如果你點擊“execute query” ,你可以得到像下面這樣的內容:
01
<?
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
02
<
response
>
03
<
lst
name
=
"responseHeader"
>
04
<
int
name
=
"status"
>0</
int
>
05
<
int
name
=
"QTime"
>1</
int
>
06
<
lst
name
=
"params"
>
07
<
str
name
=
"indent"
>true</
str
>
08
<
str
name
=
"q"
>*:*</
str
>
09
<
str
name
=
"wt"
>xml</
str
>
10
</
lst
>
11
</
lst
>
12
<
result
name
=
"response"
numFound
=
"0"
start
=
"0"
/>
13
</
response
>
索引結果為空,但這不是什麼問題,你需要插入一些示例數據。
1
$
cd
solr-4.1.0/example/exampledocs/
2
$ java -jar post.jar monitor.xml
3
4
SimplePostTool version 1.5
5
Posting files to base url http://localhost:8983/solr/update using content-
type
application/xml..
6
POSTing
file
monitor.xml
7
1 files indexed.
8
COMMITting Solr index changes to http://localhost:8983/solr/update..
現在你可以返回查詢界面,這次就會有一個文檔返回。
Collection的數據結構是在schema文件中定義的。
1
$ vim solr-4.1.0/example/solr/collection1/conf/schema.xml
這個文件有非常多的注釋,你可以很容易分辨出他們是做什麼的。如果你要修改scheme文件,請不要刪除名叫“text”的字段(如果沒很好的理由),他是和另外的字段和查詢語句中關聯的(包括select, look等等)。
01
$ grep text solr-4.1.0/example/solr/collection1/conf/schema.xml | grep copy
02
03
<
copyField
source
=
"cat"
dest
=
"text"
/>
04
<
copyField
source
=
"name"
dest
=
"text"
/>
05
<
copyField
source
=
"manu"
dest
=
"text"
/>
06
<
copyField
source
=
"features"
dest
=
"text"
/>
07
<
copyField
source
=
"includes"
dest
=
"text"
/>
08
<
copyField
source
=
"title"
dest
=
"text"
/>
09
<
copyField
source
=
"author"
dest
=
"text"
/>
10
<
copyField
source
=
"description"
dest
=
"text"
/>
11
<
copyField
source
=
"keywords"
dest
=
"text"
/>
12
<
copyField
source
=
"content"
dest
=
"text"
/>
13
<
copyField
source
=
"content_type"
dest
=
"text"
/>
14
<
copyField
source
=
"resourcename"
dest
=
"text"
/>
15
<
copyField
source
=
"url"
dest
=
"text"
/>
如果你使用的是關系數據庫,你不希望有重復的數據。Solr不是一個數據庫,多數字段也被處理成文本字段,默認request handler就是這樣。
從PHP訪問Solr需要一個客戶端。我建議從PECL下載一個。它快速,API清晰,文檔優良。不過要注意,這個擴展現在版本1.0.2,不支持Solr 4.x。Solr 3.x和4.x的協議有微小不同。不過別擔心,我已經做了修改,你可以從https://github.com/lukaszkujawa/php-pecl-solr下載兼容版本。我已經用了一段時間,是可靠的。它和官方的有點差別在SolrClient構造函數中多一個Solr版本參數。這個補丁將會發布在官方版本中,你不用擔心此後的兼容性。
1
$ git clone https://github.com/lukaszkujawa/php-pecl-solr.git
2
$
cd
php-pecl-solr/
3
$ phpize
4
$
whereis
php-config
5
php-config: /usr/bin/php-config /usr/bin/X11/php-config
6
$ ./configure --with-php-config=/usr/bin/php-config
7
$
make
8
$
make
install
添加到你的php.ini
1
extension=solr.so
重啟Web服務器
1
$ /etc/init.d/apache2 restart
現在就可以寫php添加內容到索引中了。
view source print?01
<?php
02
03
$options
=
array
(
04
'hostname'
=>
'127.0.0.1'
,
05
);
06
07
$client
=
new
SolrClient(
$options
,
"4.0"
);
// 參數4.0針對Solr4.x,其他版本時忽略
08
09
$doc
=
new
SolrInputDocument();
10
11
$doc
->addField(
'id'
, 100);
12
$doc
->addField(
'title'
,
'Hello Wolrd'
);
13
$doc
->addField(
'description'
,
'Example Document'
);
14
$doc
->addField(
'cat'
,
'Foo'
);
15
$doc
->addField(
'cat'
,
'Bar'
);
16
17
$response
=
$client
->addDocument(
$doc
);
18
19
$client
->commit();
20
21
/* ------------------------------- */
22
23
$query
=
new
SolrQuery();
24
25
$query
->setQuery(
'hello'
);
26
27
$query
->addField(
'id'
)
28
->addField(
'title'
)
29
->addField(
'description'
)
30
->addField(
'cat'
);
31
32
$queryResponse
=
$client
->query(
$query
);
33
34
$response
=
$queryResponse
->getResponse();
35
36
print_r(
$response
->response->docs );
如果你添加的文檔不止一條,她也可以處理得很好,而不需要頻繁的commit。
知道Solr如何工作是很有價值的,你可以在很多項目中使用。她有個很棒的功能可以讓你一次請求就可以拉取所有需要的數據。當然,你掌握她需要耗費一些時間,但這值得你付出。Solr擁有一個活躍的社區和完整的文檔資源,如果你還擔心在項目中使用,請翻閱Solr 3 企業搜索服務器,她不僅僅是讓你快速搭建起搜索服務,還是你數據挖掘的基礎。