Solr6.6總結(二)功能測試
今天也做了很多solr在PHP下的測試,學到不少東西。先把昨天java測試環境說一下,再說PHP的。
solr Java客戶端環境
1,新建一個java專案;
2.將solr-6.6.0\dist\solrj-lib下的jar包複製到專案lib目錄下,將solr-6.6.0\dist下的solr-solrj-6.6.0.jar複製到lib目錄下,把所有jar包add to build path;
3編寫程式碼測試,目錄結構和程式碼如下圖
java增刪改查的具體寫法在這裡就不說了,因為主要要講PHP的。
Solr PHP環境
通過官方文件https://wiki.apache.org/solr/IntegratingSolr
PHP的第三方lib也有很多,
我這裡隨便選了第一個solarium,誰叫他放第一個呢。
然後找到 http://www.solarium-project.org/ 和github網址 https://github.com/solariumphp/solarium
我先把github專案下下來,執行sample。需要composer。
下下來之後我解壓到solariumsample下,執行composer install,會自動下載依賴,下好之後目錄如下
然後修改examples目錄下的config.dist.php配置檔案,solr伺服器的host,port和path,注意預設的path是/solr是不對了,應該到core層。
<?php
$config = array(
'endpoint' => array(
'localhost' => array(
'host' => '127.0.0.1',
'port' => 8080,
'path' => '/solr/new_core',
)
)
);
配置php伺服器環境,然後訪問examples下的index.html
http://localhost:8090/examples/index.html 就可以檢視demo了,點選check-solarium-and-ping應該出現如下介面
然後我在另一個Thinkphp專案下安裝環境,直接在專案根目錄下命令列執行
composer require solarium/solarium
就會下載相關依賴。
在某個controller下寫了如下測試程式碼
config.php下新增如下配置
'SOLR_CONFIG'=>array(
'endpoint' => array(
'localhost' => array(
'host' => '127.0.0.1',
'port' => 8080,
'path' => '/solr/new_core',
)
)
),
提取檔案內容到solr供搜尋
/**
* 新增檔案
*/
public function testAddFile()
{
//建立client
require '/vendor/autoload.php';
$client = new \Solarium\Client(C('SOLR_CONFIG'));
//建立一個提取查詢
$query = $client->createExtract();
//專案Uploads/solr目錄下有一個測試doc檔案
$query->setFile($_SERVER['DOCUMENT_ROOT'] . "/Uploads/solr/test.docx");
//solr會將檔案的額外資訊儲存到attr開頭的欄位中,為什麼是attr,這個是和managed-schema檔案配置相關的,field,dynamicField,copyField
//你也可以不要這句測試一下看看什麼結果,還有一些其他設定也可以自行測試下
$query->setUprefix("attr_");
//$query->addParam("literal.id", "10000");跟下面的$doc->id = '10000';效果一樣,設定id,id是必須的。
$query->addParam("fmap.content", "attr_content");//檔案內容content對映成attr_content
//$query->setExtractOnly(false);//預設就是false,設定為true的話就只提取檔案內容,然後返回(response中獲取內容),而不會新增到solr資料中
$doc = $query->createDocument();
$doc->id = '10000';//id不存在是add,id存在是update
$doc->title = '這是我的測試標題';//設定額外的欄位
$query->setDocument($doc);
$query->setCommit(true);
//$query->setOmitHeader(false);
$result = $client->extract($query);
// echo 'Add status: ' . $result->getStatus() . '<br/>';
//StatusCode為200表示成功
echo 'Add status: ' . $result->getResponse()->getStatusCode() . '<br/>';
}
上傳結果:
伺服器後臺查詢
(你可能看到了一個searchkey欄位,這個欄位我們稍後討論,solr的配置選項挺多,需要不停優化)
刪除solr資料
public function testDel()
{
require '/vendor/autoload.php';
$client = new \Solarium\Client(C('SOLR_CONFIG'));
$query = $client->createUpdate();
//還記得新增的時候必須設定id嗎,可以按id刪除,查詢刪除等
$query->addDeleteById("10000");
//$query->addDeleteQuery("*:*");//刪除所有
$query->addCommit();
$result = $client->update($query);
echo 'Delete status: ' . $result->getStatus() . '<br/>';
}
刪除結果
在查詢一下,已經沒有了
客戶端查詢
public function testQuery()
{
require '/vendor/autoload.php';
$client = new \Solarium\Client(C('SOLR_CONFIG'));
$query = $client->createSelect();
//$query->setQuery("*:*");//查詢所有
// $query->setQuery("searchkey:技術");//下面解釋
$query->setQuery("title:測試");
//$query->addFilterQuery()//多重條件,還沒怎麼測試
//返回那些欄位,不設定就是所有
$query->setFields("id,title,attr_content");
//分頁
$query->setStart(0);
$query->setRows(10);
//高亮相關搜尋詞
$hl = $query->getHighlighting();
$hl->setFields('title, attr_content');
$hl->setSimplePrefix('<font color="red" >');
$hl->setSimplePostfix('</font>');
// this executes the query and returns the result
$resultset = $client->select($query);
$highlighting = $resultset->getHighlighting();
// display the total number of documents found by solr
echo 'NumFound: ' . $resultset->getNumFound();
// show documents using the resultset iterator
foreach ($resultset as $document) {
echo '<hr/><table>';
// the documents are also iterable, to get all fields
foreach ($document as $field => $value) {
// this converts multivalue fields to a comma-separated string
if (is_array($value)) {
$value = implode(', ', $value);
}
echo '<tr><th>' . $field . '</th><td>' . $value . '</td></tr>';
}
echo '</table><br/><b>Highlighting results:</b><br/>';
// highlighting results can be fetched by document id (the field defined as uniquekey in this schema)
$highlightedDoc = $highlighting->getResult($document->id);
if ($highlightedDoc) {
foreach ($highlightedDoc as $field => $highlight) {
echo implode(' (...) ', $highlight) . '<br/>';
}
}
}
}
查詢結果
(這裡新增的時候,如何把doc檔案前面的一些附加內容(date 2017-08-31T10:28:00Z cp:revision 5 extended-properties:AppVersion……)去掉,還不知道。我知道一種方式,就是extrat的時候,設定extractOnly為true,返回的response裡面有一個值只有doc正文內容,然後再add到solr,但是我覺得是不是太麻煩了,是否有引數或者方法可以設定,還需在研究研究。)(9.4日更新,重新設定一遍後沒有這個問題了,提取內容也正常了,還不確定是哪裡的配置出了問題,WEB-INFO/lib目錄下不能亂添東西)
再說說searchkey
我們搜尋的時候可能要一個關鍵詞對多個欄位搜尋,比如搜“計算機”,我們既要把標題中包含“計算機”的條目搜出來,也要把內容中包含計算機的條目搜出來。
我開啟我的solr_home\new_core\conf下的managed-schema檔案,如下,欄位很多,沒截全。
可以看到attr_*是dynamicField, 理解了所有匹配形式的都是dynamicField。
field就是些明確的欄位
在客戶端新增欄位的時候,欄位必須在這裡有定義,明確的或匹配的,否則會報錯欄位不存在。
說到這兒後臺的schema對應的就是這個檔案中定義的欄位和動態欄位
copyfield是啥呢?
就是用於解決上面的問題。把source欄位的內容,copy到dest欄位。我這裡把title欄位copy到searchkey欄位,把attr_content欄位也copy到searchkey欄位,新增的時候就會出現上面的searchkey欄位,他是一個數組,包含title和attr_content,然後搜尋的時候
$query->setQuery("searchkey:技術");
就可以搜尋出title或者attr_content包含”技術”的內容了,結果如下
這裡只是測試,沒考慮效率問題,這裡content很長,這樣對映的話content的內容相當於存了2遍,儲存的時候可能並沒有存2遍,但至少傳輸列印的時候,傳了2遍,所以肯定不好,知道道理了,自行優化。
還有些東西沒說,也有些東西沒研究好,如中文分詞,搜尋評分系統,搜尋過濾,等等。比如我遇到,只搜尋一個字母,返回的結果為空,我猜是匹配度太低,所以為空,但有時候我們可能又要這種結果,怎麼配置和優化還要再研究。