1. 程式人生 > >Solr6.6總結(二)功能測試

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

,我們可以看到各個語言如何整合solr客戶端。
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遍,所以肯定不好,知道道理了,自行優化。

還有些東西沒說,也有些東西沒研究好,如中文分詞,搜尋評分系統,搜尋過濾,等等。比如我遇到,只搜尋一個字母,返回的結果為空,我猜是匹配度太低,所以為空,但有時候我們可能又要這種結果,怎麼配置和優化還要再研究。