使用 Ubuntu 14 + Solr 5.3.1 做 CBETA Search Engine

2015.10.18

檢查 OS 是否為 64bit

64bit 的 Java 才能使用 4GB 以上的 RAM。

執行

uname -m

如果顯示 x86_64 表示這是 64 bit kernel,如果顯示 i686 表示這是 32 bit kernel.

install solr 5.3.1

參考 Apache Solr Reference Guide => Managing Solr => Taking Solr to Production

安裝 Java

如果安裝 default-jre,後面執行 Solr 安裝程式時會有錯誤訊息:

This script requires extracting a WAR file with either the jar or unzip utility, please install these utilities or contact your administrator for assistance.

所以安裝 default-jdk

sudo apt-get install default-jdk

查看 java 版本

java -version

得到類似以下資訊

java version "1.7.0_79"
OpenJDK Runtime Environment (IcedTea 2.5.6) (7u79-2.5.6-0ubuntu1.14.04.1)
OpenJDK 64-Bit Server VM (build 24.79-b02, mixed mode)

注意上面要有 64-bit 的字樣才是 64-bit 的 Java, 才能使用 4GB 以上的記憶體。

下載 solr-5.3.1

http://www.apache.org/dyn/closer.lua/lucene/solr/5.3.1

把 install_solr_service.sh 從壓縮檔裡取出來放在目前目錄

tar xzf solr-5.3.1.tgz solr-5.3.1/bin/install_solr_service.sh --strip-components=2

執行安裝程式

sudo bash ./install_solr_service.sh solr-5.3.1.tgz

這個安裝程式的預設值

  • 將 solr 軟體解壓縮到 /opt/solr-5.3.1,並建立一個 symbolic link /opt/solr 指到 /opt/solr-5.3.1
  • 設定 solr 將 log, index 等會異動的檔放在 /var/solr
  • 建立一個使用者叫做 solr,以這個使用者來執行 solr,這個使用者會是 /opt/solr 以及 /var/solr 的 owner

安裝完作後,Solr 會安裝成一個 service 在背景執行 (port 8983). 可以執行以下命令驗證

sudo service solr status

防火牆允許 8983

sudo ufw allow 8983

這時從 client 連 http://xxx.ddbc.edu.tw:8983 應該可以看到 solr 管理界面。

Solr Home Directory

Solr home 目錄預設是在 /var/solr/data,這個資料夾下會有一個 solr.xml.

環境設定

編輯 /var/solr/solr.in.sh,根據實務情況設定記憶體:

#SOLR_HEAP="512m"
SOLR_JAVA_MEM="-Xms16g -Xmx16g"

create core for cbeta

從 solr 安裝目錄複製設定檔範例

sudo mkdir /var/solr/data/cbeta
sudo mkdir /var/solr/data/cbeta/data
sudo touch /var/solr/data/cbeta/core.properties
sudo cp -a /opt/solr/server/solr/configsets/basic_configs/conf /var/solr/data/cbeta/conf
sudo chown -R solr:solr /var/solr/data/cbeta

取消 autoCommit

因為要整批大量匯入 CBETA 資料,最後才做 commit (solr 將變更寫入索引檔),否則容易產生 timeout,所以取消 autoCommit。

編輯 /var/solr/data/cbeta/conf/solrconfig.xml,把以下兩段註解掉:

<!--
  <autoCommit> 
    <maxTime>${solr.autoCommit.maxTime:15000}</maxTime> 
    <openSearcher>false</openSearcher> 
  </autoCommit>
-->
<!--
  <autoSoftCommit> 
    <maxTime>${solr.autoSoftCommit.maxTime:-1}</maxTime> 
  </autoSoftCommit>
-->

schema

編輯 /var/solr/data/cbeta/conf/schema.xml

<field name="id" type="string" indexed="true" stored="true" required="true" multiValued="false" />
<field name="canon"    type="string"       indexed="true" stored="true"/>
<field name="category" type="string"       indexed="true" stored="true"/>
<field name="vol"      type="string"       indexed="true" stored="true"/>
<field name="work"     type="string"       indexed="true" stored="true"/><!-- 經號 -->
<field name="juan"     type="int"          indexed="true" stored="true"/>
<field name="edition"  type="string"       indexed="true" stored="true"/><!-- 宋元明等版本 -->
<field name="orig"     type="boolean"      indexed="true" stored="true"/><!-- 是否為底本 -->
<field name="text"     type="text_general" indexed="true" stored="true"/>

以上範例,需要哪些欄位可自行調整設定。我的設計是每一卷、每個校勘版本是獨立的一個檔。

準備匯入的 XML

根據上面 schema 的設計,將 CBETA XML P5a 轉為如下 XML 準備匯入 solr:

<add>
  <doc>
    <field name='id'>T0001.J1.ED:CBETA</field>
    <field name='category'>阿含部類</field>
    <field name='canon'>T</field>
    <field name='vol'>T01</field>
    <field name='work'>T0001</field>
    <field name='juan'>1</field>
    <field name='edition'>CBETA</field>
    <field name='orig'>false</field>
    <field name='text'>全文純文字放在這裡。</field>
  </doc>
</add>

上面的 id 欄位是我隨便設定,不一定要按照這格式,只要是唯一的就好。

solr 也不強制一定要有 id 欄位。

匯入 xml 到 solr

使用如下 ruby 程式,將 xml 匯入 solr

require 'rsolr'
solr = RSolr.connect :url => 'http://localhost:8983/solr/cbeta'
s = File.read('xxx.xml')
solr.update :data => s

上面程式是匯入一個檔的範例,以此為基礎,再另外寫程式將全部檔案匯入。

全部匯入完成後,使用如下 ruby 程式做 commit,告訴 solr 寫入 index:

require 'rsolr'
solr = RSolr.connect :url => 'http://localhost:8983/solr/cbeta'
solr.update :data => '<commit/>'