LoginSignup
6
6

More than 5 years have passed since last update.

Solr5.3+Postgresの連携方法

Last updated at Posted at 2015-12-29

最近、Apache Solrを触る機会があったので、個人的にもいじってみています。

PostgresのデータベースのコンテンツをSolrに流し込む必要があったのですが、Solr5でのPostgresとの連携については日本語文献が見当たらなかったので、やってみたメモを残しておきます。
Solr5になってから設定ファイル周りが結構変わっており、少し手間取りました。。

1. 環境

  • CentOS 6.6 (32bit)
  • Oracle JDK 8 Update 65
  • Apache Solr 5.3.1
  • postgresql-server 8.4.20-4.el6_7

2. Solrのインストール

ApacheのページからSolrのバイナリを環境に持っていきます。
このとき、ソースコードも一緒にダウンロードしておくと、エラーが出て詰まったときにサクっと調べられます。(解決できるかどうかは別問題だけど)

バイナリを展開。

使ってみる。
Solr Quick Startで案内されている方法だと、クラスタ構成(SolrCloud)で起動されます。

$ bin/solr start -e cloud -noprompt

Welcome to the SolrCloud example!

  --- (snip) ---

停止。

$ bin/solr stop -all ; rm -Rf example/cloud/

今回はクラスタ構成でなくシンプルに立ち上げます。

3. Postgresのインストール

Solr + PostgreSQL連携(Solr4.9)で紹介されている方法をそのまま使わせていただきました。

Postgresをインストールします。

# yum install postgresql-server

Postgresを立ち上げます。

$ sudo service postgresql initdb
[sudo] password for hashiwa:
データベースを初期化中:                                    [  OK  ]

$ sudo service postgresql start
postgresql サービスを開始中:                               [  OK  ]

Solrから接続するユーザーを作成します。(スーパーユーザーじゃないほうが良かったかも)

$ sudo su - postgres
-bash-4.1$ createuser solruser
新しいロールをスーパーユーザとしますか?  (y/n)y
-bash-4.1$ createdb postdb -O solruser

パスワードを設定します。

-bash-4.1$ psql
psql (8.4.20)
"help" でヘルプを表示します.

postgres=# alter user solruser encrypted password 'solrpassword';
ALTER ROLE
postgres=# alter user postgres encrypted password 'postgrespassword';
ALTER ROLE
postgres-# \q

認証METHODをmd5に変更します。

$ vim /var/lib/pgsql/data/pg_hba.conf

 67 # TYPE  DATABASE    USER        CIDR-ADDRESS          METHOD
 68
 69 # "local" is for Unix domain socket connections only
 70 local   all         all                               md5
 71 # IPv4 local connections:
 72 host    all         all         127.0.0.1/32          md5
 73 # IPv6 local connections:
 74 host    all         all         ::1/128               md5

Postgresサービスを再起動します。

# service postgresql restart
postgresql サービスを停止中:                               [  OK  ]
postgresql サービスを開始中:                               [  OK  ]

forumテーブルを作成します。

$ psql -U solruser -d postdb
ユーザ solruser のパスワード:
psql (8.4.20)
"help" でヘルプを表示します.

postdb=# create table forum (
postdb(# id serial primary key,
postdb(# name varchar(32),
postdb(# body varchar(1024),
postdb(# updated timestamp(0) not null default current_timestamp);
NOTICE:  CREATE TABLEはシリアル列"forum.id"用に暗黙的なシーケンス"forum_id_seq"を作成します。
NOTICE:  CREATE TABLE / PRIMARY KEYはテーブル"forum"に暗黙的なインデックス"forum_pkey"を作成します
CREATE TABLE

差分インポート用の関数とトリガーを定義します。

postdb=# CREATE LANGUAGE plpgsql;
CREATE LANGUAGE

postdb=# create function set_update_time() returns opaque as '
postdb'#   begin
postdb'#     new.updated := ''now'';
postdb'#     return new;
postdb'#   end;
postdb'# ' language 'plpgsql';
CREATE FUNCTION

postdb=# create trigger update_tri before update on forum for each row
postdb=#   execute procedure set_update_time();

このとき、テーブルは以下の状態です。

postdb=# \d forum
                                     テーブル "public.forum"
 カラム  |               型               |                        修飾語
---------+--------------------------------+-------------------------------------------------------
 id      | integer                        | not null デフォルト nextval('forum_id_seq'::regclass)
 name    | character varying(32)          |
 body    | character varying(1024)        |
 updated | timestamp(0) without time zone | not null デフォルト now()
インデックス:
    "forum_pkey" PRIMARY KEY, btree (id)
トリガ:
    update_tri BEFORE UPDATE ON forum FOR EACH ROW EXECUTE PROCEDURE set_update_time()

Solrから検索されるデータを3つ挿入しておきます。

postdb=# insert into forum (name, body) values ('Bobbie Waterbury', 'Daddy!My Daddy!');
INSERT 0 1
postdb=# insert into forum (name, body) values ('James Bond', 'Do I look like I give a damn?');
INSERT 0 1
postdb=# insert into forum (name, body) values ('Andy Dufresne', 'Get busy living, or get busy dying.');
INSERT 0 1

データは以下のように挿入されました。

$ psql -h localhost -U solruser -d postdb -t -c 'select * from forum;';
ユーザ solruser のパスワード:
  1 | Bobbie Waterbury | Daddy!My Daddy!                     | 2015-12-26 18:02:10
  2 | James Bond       | Do I look like I give a damn?       | 2015-12-26 18:02:18
  3 | Andy Dufresne    | Get busy living, or get busy dying. | 2015-12-26 18:02:28

4. JDBCのダウンロード

Postgres用のJDBCをダウンロードしておきます。

$ curl https://jdbc.postgresql.org/download/postgresql-9.4.1207.jre6.jar > postgresql-9.4.1207.jre6.jar
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  593k  100  593k    0     0  93681      0  0:00:06  0:00:06 --:--:--  129k

5. Solrの設定

Solrの設定も、Solr + PostgreSQL連携(Solr4.9)をかなり参考にさせていただきました。ただ、Solr5になったことで注意が必要なところがあります。

念のため、サーバーディレクトリをコピーして、そちらを使用します。
サーバーディレクトリは、デフォルトだとserverディレクトリとなっているので、serverディレクトリを任意のディレクトリ名でコピーします。

$ cp -r server/ hsw_server

今回は、デフォルトで用意されているコレクションであるcollection1を使用します。1
コピーしたサーバーディレクトリの、collection1のsolrconfig.xmlを編集します。

ライブラリの設定。

hsw_server/solr/collection1/conf/solrconfig.xml
  <lib dir="/home/hashiwa/solr/solr-5.3.1-bin/hsw_server/lib/" regex="postgresql-\d.*\.jar" />
  <lib dir="/home/hashiwa/solr/solr-5.3.1-bin/dist/" regex="solr-dataimporthandler-\d.*\.jar" />
  <lib dir="/home/hashiwa/solr/solr-5.3.1-bin/contrib/dataimporthandler-extras/lib/" regex=".*\.jar" />

また、Solr5ではデフォルトではスキーマレスモードになっており、schema.xmlでスキーマを指定できないようです。

RESTでスキーマを追加することもできるようですが、スキルがないのでクラシックなschema.xmlでの指定を使うことにします。

SchemaFactoryの変更。

hsw_server/solr/collection1/conf/solrconfig.xml
  <!--
  <schemaFactory class="ManagedIndexSchemaFactory">
    <bool name="mutable">true</bool>
    <str name="managedSchemaResourceName">managed-schema</str>
  </schemaFactory>
  -->
  <schemaFactory class="ClassicIndexSchemaFactory"/>

AddSchemaFieldsUpdateProcessorFactoryの設定の削除。

hsw_server/solr/collection1/conf/solrconfig.xml
    <!--
    <processor class="solr.AddSchemaFieldsUpdateProcessorFactory">
      <str name="defaultFieldType">strings</str>
      <lst name="typeMapping">
        <str name="valueClass">java.lang.Boolean</str>
        <str name="fieldType">booleans</str>
      </lst>
      <lst name="typeMapping">
        <str name="valueClass">java.util.Date</str>
        <str name="fieldType">tdates</str>
      </lst>
      <lst name="typeMapping">
        <str name="valueClass">java.lang.Long</str>
        <str name="valueClass">java.lang.Integer</str>
        <str name="fieldType">tlongs</str>
      </lst>
      <lst name="typeMapping">
        <str name="valueClass">java.lang.Number</str>
        <str name="fieldType">tdoubles</str>
      </lst>
    </processor>
    -->

リクエストハンドラの設定。
これはData Import Handlerという機能を使うための設定で、設定自体はdataconfig.xmlに記載します。

hsw_server/solr/collection1/conf/solrconfig.xml
  <requestHandler name="/dataimport-hswtest" class="org.apache.solr.handler.dataimport.DataImportHandler" >
    <lst name="defaults">
      <str name="config">dataconfig.xml</str>
    </lst>
  </requestHandler>

dataconfig.xmlの設定。
Postgresで設定したユーザーやらパスワードやらテーブルやらを設定します。

hsw_server/solr/collection1/conf/dataconfig.xml
<dataConfig>
  <dataSource name="ratings"
              driver="org.postgresql.Driver"
              url="jdbc:postgresql://localhost:5432/postdb"
              user="solruser"
              password="solrpassword" />

  <document>
    <entity name="forum"
            query="select * from forum"
            deltaQuery="select id from forum where updated >= '${dataimporter.last_index_time}'"
            deltaImportQuery="select * from forum where id=${dataimporter.delta.id}">
      <field column="id" name="id" />
      <field column="name" name="name" />
      <field column="body" name="body" />
      <field column="updated" name="updated" />
    </entity>
  </document>
</dataConfig>

また、忘れずにJDBCのjarもsolrconfig.xmlで指定した場所に置いておく必要があります。

$ cp postgresql-9.4.1207.jre6.jar /home/hashiwa/solr/solr-5.3.1-bin/hsw_server/lib/

schema.xmlを作成します。

hsw_server/solr/collection1/conf/schema.xml
<?xml version="1.0" encoding="UTF-8" ?>
<schema name="hsw-example" version="1.5">
   <field name="id" type="string" indexed="true" stored="true" required="true" />
   <field name="name" type="text_en" indexed="true" stored="true" termVectors="true" termPositions="true" />
   <field name="body" type="text_en" indexed="true" stored="true" termVectors="true" termPositions="true" />
   <field name="updated" type="timestamp" indexed="true" stored="true" termVectors="true" termPositions="true" />
   <field name="_version_" type="long" indexed="true" stored="true"/>

   <fieldType name="long" class="solr.TrieLongField" precisionStep="0" positionIncrementGap="0"/>
   <fieldType name="string" class="solr.StrField" sortMissingLast="true" />
   <fieldType name="timestamp" class="solr.TrieDateField" />
   <fieldType name="text_en" class="solr.TextField">
     <analyzer>
       <tokenizer class="solr.StandardTokenizerFactory"/>
       <filter class="solr.LowerCaseFilterFactory"/>
       <filter class="solr.StopFilterFactory" ignoreCase="true" words="lang/stopwords_en.txt" />
     </analyzer>
   </fieldType>

   <uniqueKey>id</uniqueKey>
 <!-- depricated
   <defaultSearchField>body</defaultSearchField>
   <solrQueryParser defaultOperator="AND" />
 -->
</schema>

注意点:

  • solr.LongFieldがなくなっているらしく、solr.TrieLongFieldにする必要がある
  • idをlongにすると、elevate.xmlでid=MA147LL/Aとしているからかエラーになるため、stringにする

6. Solrの起動・データインポート

いよいよSolrを触っていきます。

Solrを起動。このとき、設定したサーバーディレクトリを指定する必要があります。

$ bin/solr start -d hsw_server/
Waiting up to 30 seconds to see Solr running on port 8983 [/]
Started Solr server on port 8983 (pid=20468). Happy searching!

Solrのコンソール( http://localhost:8983/solr/ )にアクセス。

solr-01.jpg

[Core Selector]からcollection1を選択し、[DataImport]をクリックします。

solr-02.jpg

ここで、forumを選んでExecuteすると、solrconfig.xmlで設定したData Import Handlerを実行して、PostgresからデータをSolrにインポートします。
(いくら待っても画面が更新されない場合は、[Reflesh Status]を押してみる)

solr-03.jpg

成功していたら、[Query]で検索してみます。
ちゃんとPostgresに入れた3つのデータが検索されました!

solr-04.jpg

参考資料


  1. 2015/12/30追記 collection1はデフォルトでは存在しなかったかも。なければ、Solrのコンソールなどで作成してください。 

6
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
6