HOME 回資訊服務處首頁 Login
2013年第7期
簡訊
【更新提醒】微軟安全性更新 KB2823324 可能造成 Windows 7 無法正常開機
【資安公告】DNS 放大攻擊(DNS Amplification Attacks)
【資安公告】辦公資訊設備網路位址曝露風險
【院內座談】4月25日舉行「本院第16次資訊業務協調會議」暨「資訊室主管及管理者經驗交流第19次座談會」
【資安通報】近期資安通報
【教育訓練】5/2舉辦 「不用還原卡的Win7虛擬化技術」課程,歡迎同仁報名
【中心業務】「ACM Computer Package電腦資訊科技相關全文及評論專輯」採購完成
【中心業務】計算中心已完成行動版圖書館服務網頁
【院內活動】自由軟體達人募集活動開跑!
『院外活動』亞太資訊安全論壇暨台北國際資訊安全科技展
『院外活動』「2013春季電腦展」及「企業用戶展」 4/17~21世貿一館 隆重登場!
資訊應用
Solr系統建置範例說明
 
資訊應用 >
上一篇 | 返回電子報
 
Solr系統建置範例說明
 
推廣科:郭乃綺

一、 solr 簡介(說明)

  1. 概觀
     全文檢索系統是針對大量文件的內容,可輸入任意字詞的關鍵字及其邏輯運算(AND、OR 、NOT)等,進行快速內文查詢,並提供查詢結果,依其文件符合程度的評分排序或文件相關資訊分類,以便進一步進行統計、分析及彙整的系統。常見的全文檢索的資料對象有新聞、文件報告、期刋、書籍或是網站內容等。

     對內文進行搜尋最簡易的方式就是逐字比對的循序搜尋(Sequential Search)法,但是對於大量的長篇文件搜尋,就會有效率不彰的問題了。全文檢索系統採用索引的方法,也就是先將文件內容切割出字詞單元(token),再將這些字詞以「雜湊表」或「B+樹」等資料結構,建立索引檔,紀錄其文件編號及在文件中出現的位置。在進行查詢時,系統先將輸入的字串,進行字詞單元分析,再將這些字詞一一使用索引快速搜尋,接著將結果依輸入的條件進行邏輯運算,並依在文件中出現的次數等關係計算各結果的權重,最後排序輸出結果。

     某些資料庫系統中,例如MS SQL與Oracle皆有內建簡易的全文檢索功能。但是要進行較為複雜客製化的全文檢索功能,就捉襟見肘了。必須另外採用專業的全文檢索引擎才能達成了。目前開放源碼的專案中已有十年歷史的Lucene是個不錯的選擇。Lucene是Apache基金會開放源碼計畫之一,以Java語言撰寫,具有支援Unicode多國語言,在網路社群中持續發展等優點,並且有眾多的開放源碼系統以其為核心。但缺點是Lucene是以程式庫的方式提供,必需以Java語言撰寫程式才能取用,且功能繁瑣,學習期長,並不易切入進行實作。

     Solr是開放源碼的全文檢索伺服器,以Lucene 程式庫為核心,進行全文資料的索引建立和搜尋執行;並且以HTTP協定的方式提供Web service,方便各種程式語言呼叫。Solr提供強大的設定檔,在不需編寫Java碼的情況下,就可以配置供一般全文檢索用途使用;有特殊需求時,亦可依循其插件(plugin)架構,編寫擴充功能。

     Solr原為Apache基金會的子計畫之一,已於2010年併入Lucene計畫中。並於2011年中開始在Lucene中同步發行3.x版,解決了兩者版本落差的問題,更突顯Solr的重要性。

  2. 系統特性
     Solr主要的特性包括全文檢索、命中標示(hit highlighting)、層面檢索(faceted search)、動態群聚分類(clustering)、資料庫整合、文件(如WORD,PDF檔)處理及空間資料搜尋。Solr具有高度擴充性的架構,提供分散式檢索及索引資料庫複製等功能。許多的大型網站,採用Solr提供搜尋及瀏覽操作的功能。

     Solr使用Lucene搜尋程式庫,並且大幅擴充其功能!具有以下特性:

    1. 使用設定檔定義資料Schema,包含數字類別、動態欄位及唯一鍵(Unique Key)
    2. 擴充Lucene的查詢語法
    3. 層面分類搜尋及縮小範圍過濾功能
    4. 地理空間資料搜尋
    5. 使用設定檔就可設定原始資料文本分析(tokenize)及過濾(字幹處理、停用字)
    6. 可設定的搜尋結果快取(Cache)
    7. 搜尋效能優化
    8. 使用XML格式系統設定檔
    9. 提供系統管理用界面
    10. 提供監視用的系統記錄(Log)
    11. 快速增量式更新及索引複製
    12. 具有可跨數個主機的調配式分散搜尋
    13. 進行索引的原始資料,可使用JSON、XML、CSV /符號分隔的文字檔和二進制檔等格式
    14. 可從本地磁碟或HTTP來源,取得資料庫或XML文件資料,進行索引
    15. 使用Apache Tika進行豐富文件(PDF,WORD,HTML等)解析及索引
    16. 支援多個資料索引
    17. 支援多國語言資料分析

二、 安裝

  1. Windows
     依Solr tutorial(http://lucene.apache.org/solr/tutorial.html)說明,可按步就班安裝Solr系統,以及使用下載檔中的範例schema及範例資料,快速的開始執行系統,進行各項基本系統管理、檢視系統設定、檢視schema設定、進行索引建立、測試各式檢索語法、以及偵錯各項功能等工作,由此可以迅速暸解Solr的運作方式。

     下列步驟說明如何安裝solr 3.6系統、範例schema及範例資料:

    1. 系統需求
      Java 1.5或以上版本,可以在命令列使用java –version檢查系統中現有Java的版本。在Windows 7中,以「開始/搜尋程式及檔案/輸入cmd」就可以進入命令列了。命令列中輸入java –version執行後,檢查系統中現有Java的版本。假如出現「不是內部或外部命令…」,請在「開始/電腦」按滑鼠右鍵,選擇「內容」,點選「進階系統設定」,「進階」中的「環境變數」,編輯「系統環境變數」項中的Path值,加入你安裝的JRE路徑,例如:「;C:\Program Files (x86)\Java\jre6\bin」。設定如下圖:

       
      圖、Path環境變數設定
    2. 下載Solr
      在Solr首頁(http://lucene.apache.org/solr/)中,點選「Download Solr」,取得一份最新版本的Solr,例如apache-solr-3.6.0.zip。
    3. 安裝步驟
      以Windows環境為例,使用winzip,解壓縮放入D:硬碟中。
    4. 啟動系統
      Solr伺服器可在任何Java Servlet容器中執行。在Solr的example目錄中,已經包含了Jetty Servlet容器、Solr WAR及範例系統設定,可用下列指令啟動服務:
      $ cd example/
      $ java -jar start.jar
      在Windows中,進入命令列後,執行:
      d:
      cd apache-solr-3.6.0/example
      java -jar start.jar
      Jetty使用port 8983提供服務,並且在命令列中顯示log資訊。你可以使用瀏覽器讀取http://localhost:8983/solr/admin/,觀察正在執行的Solr,這也是管理介面的進入點,其畫面如下:

       
      圖一、管理介面
  2. Linux
    1. 系統需求
      Java 1.5或以上版本,可以在命令列使用java –version檢查系統中現有Java的版本。
    2. 下載Solr
      在Solr首頁(http://lucene.apache.org/solr/)中,點選「Download Solr」,取得一份最新版本 for LInux的Solr,例如apache-solr-3.6.0.tgz。
    3. 安裝步驟
      2.2.3.1 以Unix環境為例,步驟如下:
      $ ls  確認目錄下有apache-solr-3.6.0.tgz 檔案
      $ tar xvf apache-solr-3.6.0.tgz
      $ cd apache-solr-3.6.0/
      Path : /opt/apache-solr-3.5.0/example/solr
      2.2.3.2 設定init script
      SOLR_DIR="/opt/apache-solr-3.6.1/example"
      JAVA_OPTIONS="-Xmx1024m -DSTOP.PORT=8079 -DSTOP.KEY=stopkey -Dsolr.solr.home=multicore -jar start.jar"
      LOG_FILE="/var/log/solr.log"
      JAVA="/usr/bin/java"
    4. 啟動系統
      設定命令列啟動指令
       
      #!/bin/sh -e

      # Starts, stops, and restarts solr
      # chkconfig: - 97 11

      SOLR_DIR="/opt/apache-solr-3.6.1/example"
      JAVA_OPTIONS="-Xmx1024m -DSTOP.PORT=8079 -DSTOP.KEY=stopkey -Dsolr.solr.home=multicore -jar start.jar"
      LOG_FILE="/var/log/solr.log"
      JAVA="/usr/bin/java"

      case $1 in
          start)
              echo "Starting Solr"
              cd $SOLR_DIR
              $JAVA $JAVA_OPTIONS 2> $LOG_FILE &
              ;;
          stop)
              echo "Stopping Solr"
              cd $SOLR_DIR
              $JAVA $JAVA_OPTIONS --stop
              ;;
          restart)
              $0 stop
              sleep 1
              $0 start
              ;;
          *)
              echo "Usage: $0 {start|stop|restart}" >&2
              exit 1
              ;;
      esac

          啟動指令#service solr start
          關閉指令#service solr stop
          重啟指令#service solr restart

三、管理介面說明(Admin)
  管理介面(如圖一)各功能說明如下:

  1. SCHEMA:顯示目前系統schema定義檔(example\solr\conf\schema.xml)的內容。
  2. CONFIG:顯示目前系統設定檔(example\solr\conf\ solrconfig.xml)的內容。
  3. ANALYSIS:欄位分析工具。如圖二,輸入欄位類別或名稱、欄位內容及查詢字串。可觀察依schema所設定,該欄位的內容在系統中如何經過那些元件處理後建入索引;及查詢的字串如何被處理,與索引內容比對的結果,是開發階段除錯的絕佳工具。圖中測試名稱為text的欄位,索引的資料首先透過Index Analyzer中的analysis.StandardTokenizerFactory切割為數個token,其中的this因查詢比對成功,而標上藍色底色。

     
    圖二、欄位分析

  4. SCHEMA BROWSER:schema瀏覽器。Solr中的欄位相關設定分為欄位、動態欄位及欄位類別三類。如圖三顯示欄位大類中的NAME欄位,其類別為TEXT_GENERAL,其屬性為索引(indexed)、單元分析(tokenized)及儲存內容(stored),以及其索引分析器及查詢分析器設定,且已有17個文件使用該欄位。
     
    圖三、schema瀏覽器
  5. Statistics:顯示目前系統中各元件的名稱、版本及執行狀態。檢查畫面中顯示的numDocs值,可得知Solr系統已儲存幾筆文件。
  6. Make a Query:在「Query string」輸入欄中,使用Solr查詢語法,可進行查詢測試。可使用的基本語法舉例說明如下:
    輸入  說明
    *:* 語法為:欄位名:查詢字串。此為所有欄位的資料
    ipod 針對系統內定欄位text,查詢ipod字串
    >td>name:ipod 針對name欄位,查詢ipod字串
    i* 查詢含有以i開頭的資料,*為0或多個字的wildcard
    te?t 可以查詢test及text等字串, ?為1個字的wildcard
    foo AND bar NOT baz 查詢含有foo及bar,但沒有baz者
    foo && bar !baz 作用同上
    +foo bar -baz 查詢一定含有foo,可以有bar,但沒有baz者
    (jakarta OR apache) AND website 查詢含有jakarta或apache,且有website字串者
    title:"The Right Way" 針對title欄位,查詢含有The Right Way字串
    price:[2000 TO 3000] 針對price欄位,查詢介於2000到3000
    price:[* TO 1000] 查詢price小於等於1000者
  7. Make a Query – Full Interface:完整版查詢測試。例如圖四中輸入的查詢條件為:查詢name欄位為canon、過濾條件為cat欄位是electronics、由第二筆結果開始、回傳一筆資料、回傳的欄位有cat/id/name/price及評分值score、回傳格式為XML、啟動命中標示功能並標示name欄位中的內容。

     
    圖四、查詢測試

     點選「Search」後,這些查詢參數將以網址的形式組合如下,傳送到Solr伺服器:
    http://localhost:8983/solr/select?q=name%3Acanon&fq=cat%3Aelectronics&start=1&rows=1&fl=cat%2Cid%2Cname%2Cprice%2Cscore&qt=&wt=xml&hl=on&hl.fl=name
    這也是撰寫應用程式時,以HTTP方式向Solr伺服器所提交的呼叫。伺服器進行檢索後,以XML格式回傳結果如下:

    <response>
     <lst name="responseHeader">
      <int name="status">0</int>
      <int name="QTime">3</int>
      <lst name="params">
        <str name="hl.fl">name</str>
        <str name="wt">xml</str>
        <str name="hl">on</str>
        <str name="rows">1</str>
        <str name="fl">cat,id,name,price,score</str>
        <str name="start">1</str>
        <str name="q">name:canon</str>
        <str name="fq">cat:electronics</str>
      </lst>
     </lst>
     <result name="response" numFound="2" start="1" maxScore="1.3673005">
      <doc>
       <float name="score">0.8545628</float>
       <arr name="cat">
          <str>electronics</str>
          <str>multifunction printer</str>
          <str>printer</str>
          <str>scanner</str>
          <str>copier</str>
       </arr>
       <str name="id">0579B002</str>
       <str name="name">Canon PIXMA MP500 All-In-One Photo Printer</str>
       <float name="price">179.99</float>
      </doc>
     </result>
     <lst name="highlighting">
     <lst name="0579B002">
      <arr name="name">
        <str>
          <em>Canon</em> PIXMA MP500 All-In-One Photo Printer
        </str>
       </arr>
      </lst>
     </lst>
    </response>

     在responseHeader中status=0,表示查詢成功;QTime=3為耗時3ms;result中 numFound="2"表示找到2筆文件;score=0.8545628為該文件全文檢索的評分值;highlighting為命中標示,標示name欄位中的內容,以<em>標籤標示出命中字串。應用程式只要解析這個回傳的XML內容,編排後就即可在網頁中呈現檢索結果。這個功能可供程式員在開發階段檢視request及response的詳細內容。

四、multicore
 啟動multi core模式能夠讓一個solr server同時內建好幾個個別子系統的index,每個子系統可以設定自己的schema以及config檔案,透過管理介面,也能看到個別子系統的管理介面,multicore機制能夠讓solr server更具彈性,以及更寬廣的操作運用方式。solr內建的範例中,有包含2個core的設定,可以使用下列步驟啟動multi core模式:

  1. 啟動
    在 example/目錄中,以下列命令啟動jetty:
    java -Dsolr.solr.home=multicore -jar start.jar
  2. 多core同時運作
    伺服器中將有core0及core1同時運作。要讀取某個core,可用下列指令:
    http://localhost:8983/solr/core0/select?q=*:*
    http://localhost:8983/solr/core1/select?q=*:*
  3. multicore的solr server進入頁面
    在multicore的環境運作之下,於solr server的進入頁面    
    http://10.109.8.24:8983/solr/,可以看到每個core的管理介面連結進入點如下:

    每個core的管理介面網址如下:
    http://10.109.8.24:8983/solr/core0/admin/
    http://10.109.8.24:8983/solr/core1/admin/
    http://10.109.8.24:8983/solr/faq/admin/
    舉例來說,點選”Admin faq”連結,就能進入”faq”這個子系統的管理介面。


五、schema
  1. 建立索引資料
     已執行的Solr伺服器中,並無資料存在。可以經由HTTP的方式,post含有指令及資料的XML文件,更新索引檔內容。XML文件中可用的指令包括新增/更新文件、刪除文件、commit尚未寫入的修改及最佳化索引等。

     在Solr系統exampledocs目錄中,附有一些範例資料檔。其中monitor.xml檔內容如下:


    <add><doc>
    <field name="id">3007WFP</field>
    <field name="name">Dell Widescreen UltraSharp 3007WFP</field>
    <field name="manu">Dell, Inc.</field>
    <field name="cat">electronics</field>
    <field name="cat">monitor</field>
    <field name="features">30" TFT active matrix LCD, 2560 x 1600, .25mm dot pitch, 700:1 contrast</field>
    <field name="includes">USB cable</field>
    <field name="weight">401.6</field>
    <field name="price">2199</field>
    <field name="popularity">6</field>
    <field name="inStock">true</field>
    <field name="store">43.17614,-90.57341</field>
    </doc></add>

     文件中<add>標籤為新增或更新資料的指令,其中<doc>為文件資料內容,<field nam=””>為各欄位資料,一個<add>指令可包含多個<doc>文件。另外可以使用的指令有<delete>、<commit/>及<optimize/>。執行下列指令,即可將monitor.xml檔中的資料建入索引中:
     $ cd exampledocs
     $ java -jar post.jar monitor.xml
    用同樣的方法可將所有的範例文件建入索引中:
    $ java -jar post.jar *.xml
     另外Solr也提供滙入資料庫資料、滙入CSV檔、使用JSON格式、取出Word或PDF檔建入索引、或是使用SolrJ或其他程式語言所撰寫的程式產生資料送入Solr中等等的方法建立索引。
    1. 更新資料
      只要修改XML資料檔內容,再post到Solr即可修改已存入索引的資料。
    2. 刪除資料
      使用delete命令,post到Solr的更新資料網址http://localhost:8983/solr/update,即可刪除符合查詢條件的資料。通常會使用唯一值的欄位,做為選取的條件,例如:
      $ java -Ddata=args -Dcommit=no -jar post.jar "<delete><id>SP2514N</id></delete>"
      就可刪除id欄位值為SP2514N的那筆資料了。

  2. 功能展示
    Solr系統中提供使用velocity模版所撰寫的範例查詢介面,其中展示了檢索、層面分類(faceting)、命中標示、自動提示(autocomplete)及空間資訊查詢等功能,可供暸解系統及開發時參考用。以瀏覽器開啟http://localhost:8983/solr/browse,即可使用範例介面,如圖五。


    圖五、範例查詢介面

     畫面左上方顯示基本查詢及空間資訊查詢;畫面左側為各式的層面分類;畫面中間為查詢結果的各筆資料,各展示功能說明如下:

    1. autocomplete:在查詢欄位中輸入查詢條件時,依據索引中所儲存的token顯示自動完成提示,例如輸入i時,提示ipod及in。
    2. Field Facets:欄位層面分類。範例中的cat(類別)為多值欄位,例如「USB cable」資料同時屬於electronics及connector類。在畫面上點選「connector」時,結果畫面就會縮小範圍為只屬於「connector」者。
    3. Query Facets:查詢層面分類。系統內部設定以「ipod」及「GB」為查詢層面分類條件進行分類統計。
    4. Range Facets:範圍層面分類。例如:價錢範圍或製造日期範圍。
    5. Clusters:動態群聚分類,是針對搜尋結果的欄位內容,進行分析,動態的產生分類大項。伺服器必須以下列方法啟動,方可使用此分類功能:
      java -Dsolr.clustering.enabled=true -jar start.jar
    6. 命中標示:伺服器中提供命中標示元件,可指定欲標示的欄位。範例中,使用<em>標籤標示命中的內容。
    7. More Like This:相關文件搜尋是自動根據搜獲的文件內容,再搜尋出相似的文件。
    8. Spatial:空間查詢。點選左上角「Spatial」,就會出現Location Filter及Distance查詢條件欄位,可針對座標欄位進行比對。
    9. 分頁:Solr系統進行查詢時,可限定返回的開始資料位置及返回的筆數,達到分頁的功能。例如畫面顯示的「3 results found. Page 1 of 1」。
  3. FAQ 系統範例說明
     Solr系統中提供使用multicore方式,來設計不同子系統的search engine,每個子系統有其個別的目錄紀載index以及config相關設定,以FAQ系統為例,其conf/schema.xml內容如下 :

    <schema name="FAQ" version="1.0">
      <types>
       <fieldtype name="string"  class="solr.StrField" sortMissingLast="true" omitNorms="true"/>
       <fieldType name="text" class="solr.TextField">
       
        <analyzer type="index">
         <tokenizer class="solr.StandardTokenizerFactory"/>
         <filter class="solr.LowerCaseFilterFactory"/>
     
        </analyzer>
        <analyzer type="query" >
         <tokenizer class="solr.StandardTokenizerFactory"/>
         <filter class="solr.LowerCaseFilterFactory"/>

        </analyzer>
       </fieldType>
        <fieldType name="text_general" class="solr.TextField" positionIncrementGap="100">
          <analyzer type="index">
            <tokenizer class="solr.StandardTokenizerFactory"/>
            <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" enablePositionIncrements="true" />
            <filter class="solr.LowerCaseFilterFactory"/>
          </analyzer>
          <analyzer type="query">
            <tokenizer class="solr.StandardTokenizerFactory"/>
            <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" enablePositionIncrements="true" />
            <filter class="solr.LowerCaseFilterFactory"/>
          </analyzer>
        </fieldType>
      </types>
    <fields>  
      <!-- general -->
      <field name="faqID"      type="string"   indexed="true"  stored="true"   required="true"/>
      <field name="faqtitle"    type="text"   indexed="true"  stored="true"   />
      <field name="faqdesc"    type="text"   indexed="true"  stored="true"   />
      <field name="faqclassify"    type="string"  indexed="true"  stored="true" multiValued="true"  />
      <field name="text" type="text_general" indexed="true" stored="false" multiValued="true"/>
     </fields>
     <uniqueKey>faqID</uniqueKey>
     <defaultSearchField>text</defaultSearchField>

    <copyField source="faqtitle" dest="text"/>
     <copyField source="faqdesc" dest="text"/>

     <solrQueryParser defaultOperator="OR"/>
    </schema>


     其中copyField的設定,可以指定將faqtitle以及faqdesc兩個欄位複製到text這個欄位,日後如對text欄位進行搜尋,也就是設定defaultSearchField為text時,其實solr會對faqtitle以及faqdesc兩個欄位同時進行搜尋,如此能讓搜尋範圍的設定更為靈活好使用。

六、client程式PHP撰寫(資料查詢)

  1. 程式Demo
    1. 進入點 : 可以進入此頁面指定每頁顯示筆數以及查詢的字串,如”SSO” 。
       
      圖六、範例查詢介面進入點
    2. 顯示主頁面 : 此頁面的上方有顯示上一頁以及下一頁,左邊選單顯示該分類的相關查詢連結,右邊中間部分則是顯示含有”SSO”字串的相關資料連結,點選進去可看該筆詳細資訊。其中上一頁與下一頁的連結,是透過網頁參數的傳遞,指定paging的參數,以達到分頁顯示的效果,左邊的分類連結則是透過傳遞facet的參數,來做不同子分類的內容頁顯示。

      圖七、查詢介面結果總覽
    3. 閱覽下頁 : 例如在點選下一頁之後,如圖所示

      圖八、查詢介面清單顯示
    4. 查看詳細資訊
      選擇其中一筆查看其詳細資訊,顯示如下 :
       
      圖九、單筆查詢結果詳細顯示
  2. query
     程式碼參數設定如下 : 讓使用者透過介面輸入查詢字串$query_str,用urlencode函式轉換過後,就能變成可以讓solr server辨識的設定字串,solr server會依據所下的條件進行查詢。

    $query_str = $_GET['condition'];
    $solr_server = 'http://10.109.8.24:8983/solr/';
    $core_name = "faq";
    $url_query_str = urlencode($query_str);
    $paging_parameter = "&start=".$pageStart."&rows=".$interval;
    $fields_parameter = "&fl=faqID%2Cfaqclassify%2Cscore";
    $hightlight_parameter = "&hl=on&hl.fl=faqID%2Cfaqtitle%2Cfaqdesc&hl.fragsize=100";
    $facet_parameter = "&facet=true&facet.field=faqclassify&facet.mincount=1";

    $query_url = $solr_server . $core_name . '/select?q=' . $url_query_str . $paging_parameter .
               $default_query_parameter. $fields_parameter.$hightlight_parameter.$facet_parameter;
    $default_query_parameter. $fields_parameter .$facet_parameter;
    $ret_str = file_get_contents($query_url);
    print_r($query_url);
    echo '<pre>';var_dump($ret_str);echo '</pre>';
    $rsp = json_decode($ret_str);
     

  1. hl
     程式碼參數設定如下 :hl為用以將特定欄位加強顏色標示的參數,如hl=on代表要將此功能啟動,其他詳細參數設定可見參考文獻[6]。
    $solr_server = 'http://10.109.8.24:8983/solr/';
    $core_name = "faq";
    $url_query_str = urlencode($query_str);
    $paging_parameter = "&start=".$pageStart."&rows=".$interval;
    $fields_parameter = "&fl=faqID%2Cfaqclassify%2Cscore";
    $hightlight_parameter = "&hl=on&hl.fl=faqID%2Cfaqtitle%2Cfaqdesc&hl.fragsize=100";
    $facet_parameter = "&facet=true&facet.field=faqclassify&facet.mincount=1";

    $query_url = $solr_server . $core_name . '/select?q=' . $url_query_str . $paging_parameter .
               $default_query_parameter. $fields_parameter.$hightlight_parameter.$facet_parameter;
    $default_query_parameter. $fields_parameter .$facet_parameter;
    $ret_str = file_get_contents($query_url);
    print_r($query_url);
    echo '<pre>';var_dump($ret_str);echo '</pre>';
    $rsp = json_decode($ret_str);

  1. facet
     程式碼參數設定如下 : facet設定將特定欄位作為子分類顯示的參數,如facet=true代表要將此功能啟動,facet.field=faqclassify代表將faqclassify此欄位,當成是進行子分類的欄位,其他詳細參數設定可見參考文獻[7]。
    $solr_server = 'http://10.109.8.24:8983/solr/';
    $core_name = "faq";
    $url_query_str = urlencode($query_str);
    $paging_parameter = "&start=".$pageStart."&rows=".$interval;
    $fields_parameter = "&fl=faqID%2Cfaqclassify%2Cscore";
    $hightlight_parameter = "&hl=on&hl.fl=faqID%2Cfaqtitle%2Cfaqdesc&hl.fragsize=100";
    $facet_parameter = "&facet=true&facet.field=faqclassify&facet.mincount=1";

    $query_url = $solr_server . $core_name . '/select?q=' . $url_query_str . $paging_parameter .
               $default_query_parameter. $fields_parameter.$hightlight_parameter.$facet_parameter;
    $default_query_parameter. $fields_parameter .$facet_parameter;
    $ret_str = file_get_contents($query_url);
    print_r($query_url);
    echo '<pre>';var_dump($ret_str);echo '</pre>';
    $rsp = json_decode($ret_str);

  1. paging 分頁
     程式碼參數設定如下 : 在搜尋結果頁,透過設定start與rows,可以指定此頁從第x筆開始顯示,rows則可用以指定每頁顯示筆數,因此,假設寫程式時,想要設計如google般將搜尋結果換頁的效果,就可以設定第一頁從第一筆顯示到第x筆,第二頁(start=x+1)從第(x+1)筆開始顯示,依此類推。
    $solr_server = 'http://10.109.8.24:8983/solr/';
    $core_name = "faq";
    $url_query_str = urlencode($query_str);
    $paging_parameter = "&start=".$pageStart."&rows=".$interval;
    $fields_parameter = "&fl=faqID%2Cfaqclassify%2Cscore";
    $hightlight_parameter = "&hl=on&hl.fl=faqID%2Cfaqtitle%2Cfaqdesc&hl.fragsize=100";
    $facet_parameter = "&facet=true&facet.field=faqclassify&facet.mincount=1";

    $query_url = $solr_server . $core_name . '/select?q=' . $url_query_str . $paging_parameter .
               $default_query_parameter. $fields_parameter.$hightlight_parameter.$facet_parameter;
    $default_query_parameter. $fields_parameter .$facet_parameter;
    $ret_str = file_get_contents($query_url);
    print_r($query_url);
    echo '<pre>';var_dump($ret_str);echo '</pre>';
    $rsp = json_decode($ret_str);

七、client程式PHP撰寫

  1. curl命令列操作 (client post)
    1. 使用cURL命令列,新增資料: 由json檔
      curl 'http://localhost:8983/solr/faq/update/json?commit=true'
      --data-binary @dumpData.json -H 'Content-type:application/json'
    2. 使用cURL命令列,刪除資料: 資料在命令列中
      curl http://localhost:8983/solr/faq/update/json?commit=true -H "Content-type:application/json" -d '{"delete":{"query":"faqID:12345"}}'
  2. 新增
     程式碼如下所示 : $cart為設定要透過curl塞入solr index 的單筆資料設定,其中curl所提供的函式curl_setopt,裡面的參數可以經由指定,將相關數值一一塞入。如CURLOPT_URL是用以設定solr server要更新的路徑CURLOPT_POSTFIELDS,則是帶入要塞入solr index的資料$cart。

    $cart =array(
     "add" => array(
       "doc" => array(
           "faqID" => "$faqID",
           "faqtitle" => "$faqtitle",
           "faqdesc" => "test3",
           "faqclassify" => "iasccArtical"
        )
       )
     );
    $ch = curl_init();// set url
     curl_setopt($ch, CURLOPT_URL,"http://10.109.8.24:8983/solr/faq/update/json");

     curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");                                                                    
     curl_setopt($ch, CURLOPT_HTTPHEADER, array(
        'Content-Type: application/json'
        )
     );

     curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode( $cart ));
     curl_setopt($ch, CURLOPT_POST, 1);
     curl_close($ch);

  3. 刪除
     程式碼如下所示 : 透過$cart資料的設定,指定這次要執行delete動作,而$range的值即為指定要進行刪除的資料ID。

    $range = "faqID:[12347 TO 12347]";
    $cart =array(

        "delete" => array(
           "query" => $range
        )
     );
     echo json_encode( $cart );
     $ch = curl_init();// set url
     curl_setopt($ch, CURLOPT_URL,"http://10.109.8.24:8983/solr/faq/update/json");

     curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");                                                                    
     curl_setopt($ch, CURLOPT_HTTPHEADER, array(
        'Content-Type: application/json '
        )
     );

     curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode( $cart ));
     curl_setopt($ch, CURLOPT_POST, 1);
     $output = curl_exec($ch);
        if (curl_errno($ch)) {
            echo "Error Msg";
            print curl_error($ch);
        } else {
            echo $output;
            curl_close($ch);
        }

  4. Commit
     程式碼如下所示 : Commit的進行,是為了減輕solr每次update或是delete都要存取一次solr index所造成的運算負擔,可以將update與delete的動作先buffer起來,等到到達一定數量之後,再一次透過commit指令,將這些buffer區的資料,一次更新到solr index裡面,所以設計commit的指令,可以方便後來建置client端介面的progammer,加以靈活運用。

    $cart = '{ "commit": {} }';
    $ch = curl_init();// set url
    curl_setopt($ch, CURLOPT_URL,"http://10.109.8.24:8983/solr/faq/update/json");

    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");                                                                    
     curl_setopt($ch, CURLOPT_HTTPHEADER, array(
        'Content-Type: application/json '
        )
     );
     curl_setopt($ch, CURLOPT_POSTFIELDS, $cart );
     curl_setopt($ch, CURLOPT_POST, 1);
     $output = curl_exec($ch);
    curl_close($ch);

八、結論與展望

  1. 應用系統開發
     開發使用Solr的應用系統,有多種程式語言可使用,例如Ruby、PHP、Java、Python、.NET、Perl及Javascript。基本上可進行HTTP協定通訊及讀寫XML或JSON格式資料的程式語言,都能使用。

     供PHP語言用的常見程式庫有solr-php-client及Apache Solr PHP Extension,另外直接使用PHP的file_get_contents() function直接讀寫Solr server也很方便。在Solr的default安裝中已包含的client端程式庫,有ruby的solr-ruby,其中也附上完整的範例;另外也包含供Java語言開發使用的SolrJ程式庫。

     某些知名的開放源碼專案中,也提供Solr的模組或插件,做為內部資料檢索的解決方案,例如ColdFusion、Django、Drupal、eZ Find、Plone、TYPO3及WordPress等專案,。

  2. 結論
     Solr已將全文檢索伺服器包裝成只要經由修改系統設定及schema定義二個XML格式的文字檔,就可運作。以MVC系統架構觀點而言,Solr已提供了Model的功能,應用系統只要將心力專注於View的畫面配置與UI設計,以及Controller的request的HTTP URL參數編排、回傳結果的XML/JSON內容解析就可以完成系統了。Solr大幅的簡化全文檢索系統開發的複雜度。

九 參考文獻

  1. highlight參數設定 http://wiki.apache.org/solr/HighlightingParameters
  2. curl 指令說明http://www.lornajane.net/posts/2011/posting-json-data-with-php-curl
  3. 使用curl 指令將json格式資料上傳 http://www.lornajane.net/posts/2011/posting-json-data-with-php-curl
  4. What are Multiple Cores?  http://wiki.apache.org/solr/CoreAdmin
  5. 全文檢索伺服器Solr初探 http://newsletter.ascc.sinica.edu.tw/news/read_news.php?nid=2288
  6. HighlightingParameters http://wiki.apache.org/solr/HighlightingParameters
  7.  SimpleFacetParameters http://wiki.apache.org/solr/SimpleFacetParameters



上一篇 | 返回電子報
 
 本電子報所有文字、圖片版權為中央研究院所有 。 電子報出版系統由中央研究院資訊服務處開發。