@blog.justoneplanet.info

日々勉強

SolrでDataImportHandlerを使う

前回の続き。

■インポート元などの設定

solr/conf/data-config.xml

はてなのドキュメントが少し違っていて、以下のようにdocumentノードが無いとエラーになる。

<?xml version="1.0" encoding="UTF-8" ?>
<dataConfig>
  <dataSource
    name="dbname"
    driver="com.mysql.jdbc.Driver"
    url="jdbc:mysql://localhost/dbname"
    user="username"
    password="password"
    batchSize="-1"
    useUnicode="true"
    characterEncoding="utf8"
    useOldUTF8Behavior="true"
    readOnly="true" />
  <document name="items">
    <entity
      name="table"
      dataSource="dbname"
      query="
        SELECT
          `id`,
          `key`,
          `value`
        FROM
          `table`
        WHERE
          `created` &lt; DATE_SUB(CURRENT_TIMESTAMP, INTERVAL 7 DAY)
        "
      deltaQuery="
        SELECT
          `id`
        FROM
          `table`
        WHERE
          `created` &lt; DATE_SUB(CURRENT_TIMESTAMP, INTERVAL 7 DAY)
        AND
          `created` &gt; DATE_SUB('${dataimporter.last_index_time}', INTERVAL '7 9' DAY_HOUR)
        "
     deltaImportQuery="
        SELECT
          `id`,
          `key`,
          `value`
        FROM
          `table`
        WHERE
          `id` = '${dataimporter.delta.id}'
        "
      transformer="ClobTransformer,DateFormatTransformer">
    </entity>
  </document>
</dataConfig>

solr/conf/solrconfig.xml

以下の記述を追加する。

  <requestHandler name="/dataimport" class="org.apache.solr.handler.dataimport.DataImportHandler">
    <lst name="defaults">
     <str name="config">data-config.xml</str>
    </lst>
  </requestHandler>

エラー1

後述のURLでインポートをすると以下のようなエラーが発生する。

Caused by: java.lang.ClassNotFoundException: com.mysql.jdbc.Driver
        at java.net.URLClassLoader$1.run(URLClassLoader.java:217)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:205)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:321)
        at java.net.FactoryURLClassLoader.loadClass(URLClassLoader.java:615)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:266)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:264)
        at org.apache.solr.core.SolrResourceLoader.findClass(SolrResourceLoader.java:378)

以下のコマンドを実行してJDBCドライバを配置する。

wget http://www.mysql.com/get/Downloads/Connector-J/mysql-connector-java-5.1.22.tar.gz/from/http://cdn.mysql.com/
tar xvzf mysql-connector-java-5.1.22.tar.gz
cp mysql-connector-java-5.1.22/mysql-connector-java-5.1.22-bin.jar ./lib/

■インポートの実行

以下のURLにアクセスする。

http://localhost/solr/admin/dataimport.jsp?handler=/dataimport

ちょっと不確かなのだが[debug now]の後に[full clean import]をすれば0からインデックスが構築される。構築中は古いインデックスが使われるようだ。

■差分インポートの実行

ドキュメントを見ると差分インポートの仕方もあるようなのだが、(Jetty経由で叩く?)いまいちよくわからないので、以下のようにcrontabとcurlで実行することにした。

00 * * * * curl "http://localhost/solr/dataimport?clean=false&commit=true&command=delta-import"

参考

Apache SolrをPHPから使う

file_get_contentsとかでlocalhostを叩いても可能ではあるが、Apache Solrを使ってみることにする。

Apache Solr のバージョン 1.3 および 1.4 の両方と互換性があります。

上述のように記載されているが3.6でもとりあえずドキュメントの追加はできる。

■php-pecl-solrのインストール

面倒なのでremiを使う。

yum install --enablerepo=remi,epel php-pecl-solr

mac

peclでインストールする。

pecl install solr

windowsは知らん。

■ドキュメントの追加

以下のようにして、ドキュメントを追加する事ができる。

$client = new SolrClient(array(
    'hostname' => 'localhost',
    'port'     => 8983,
));
var_dump($client);

$doc = new SolrInputDocument();
$doc->addField('id',        '1');
$doc->addField('name',      '梅雨');
$doc->addField('value',     '蒸し暑い,湿気');
$doc->addField('is_public', true);

$updateResponse = $client->addDocument($doc);
$updateResponse = $client->commit();// commitしないとindexが更新されない
var_dump($updateResponse);

■ドキュメントの取り出し

以下のようにしてクエリを発行する事ができる。

$client = new SolrClient(array(
    'hostname' => 'localhost',
    'port'     => 8983,
));
$query = new SolrQuery('*:*');
$query->setStart(0);
$query->setRows(300);
$query_response = $client->query($query);
$response = $query_response->getResponse();
var_dump($response);
/*
object(SolrObject)#4 (2) {
  ["responseHeader"]=>
  object(SolrObject)#5 (3) {
    ["status"]=>
    int(0)
    ["QTime"]=>
    int(0)
    ["params"]=>
    object(SolrObject)#6 (4) {
      ["indent"]=>
      string(2) "on"
      ["wt"]=>
      string(3) "xml"
      ["q"]=>
      string(3) "*:*"
      ["version"]=>
      string(3) "2.2"
    }
  }
  ["response"]=>
  object(SolrObject)#7 (3) {
    ["numFound"]=>
    int(2)
    ["start"]=>
    int(0)
    ["docs"]=>
    array(2) {
      [0]=>
      object(SolrObject)#8 (8) {
        ["created"]=>int(123456789)
        ["face"]=>string(5) "梅雨"
        ["id"]=>string(1) "1"
        ["is_public"]=>bool(true)
        ["tag"]=>string(15) "蒸し暑い,湿気"
      }
      [1]=>
      object(SolrObject)#9 (8) {
        ["created"]=>int(123456789)
        ["face"]=>string(12) "秋雨"
        ["id"]=>string(1) "2"
        ["is_public"]=>bool(true)
        ["tag"]=>string(15) "蒸し暑い,湿気"
      }
    }
  }
}
*/

wt=phpとクエリを投げるとphpの配列で返ってくるのだが以下のメソッドがどうも上手く機能しない。

$client->setResponseWriter("phpnative");
//SolrResponse::getResponse(): Error unserializing raw response.
//Uncaught exception 'SolrException' with message 'Error un-serializing response'

参考

Apache Solrを使ってみる

■インストール

macにインストールする

Javaは既に入ってると思うので、以下のコマンドでダウンロードする。

wget http://ftp.tsukuba.wide.ad.jp/software/apache/lucene/solr/3.6.0/apache-solr-3.6.0.zip
unzip apache-solr-3.6.0.zip
cd apache-solr-3.6.0

CentOSにインストールする

Javaが必要なので以下のコマンドでJavaをインストールする。

yum install java-1.6.0-openjdk
java -version

以下のコマンドでダウンロードする。

wget http://ftp.tsukuba.wide.ad.jp/software/apache/lucene/solr/3.6.0/apache-solr-3.6.0.tgz
tar xvzf apache-solr-3.6.0.tgz
cd apache-solr-3.6.0

■設定

example/conf/schema.xml

<schema>
 <!--typesは大体元のxmlファイルを使う-->
 <fields>
   <field name="id"        type="string"       indexed="true" stored="true"  required="true" /> 
   <field name="name"      type="text_ja"      indexed="true" stored="true"  required="true" />
   <field name="value"     type="text_ja"      indexed="true" stored="true"  required="true" />
   <field name="text"      type="text_ja"      indexed="true" stored="false" multiValued="true"/>
   <field name="is_public" type="boolean"      indexed="true" stored="true"  required="true" />
 </fields>
 <uniqueKey>id</uniqueKey>
 <copyField source="name"  dest="text"/>
 <copyField source="value" dest="text"/>
</schema>

ポート変更

デフォルトは8983で動作するが変更したい場合は以下のコマンドを実行する。

vim etc/jetty.xml

以下の部分を

<Set name="port"><SystemProperty name="jetty.port" default="8983"/></Set>

以下のように変更する。

<Set name="port"><SystemProperty name="jetty.port" default="8080"/></Set>

■データの準備

example/exampledocs/mydata.xml

同じディレクリに入ってるデータを参考に以下のようにしてみる。

<add>
<doc>
  <field name="id">1</field>
  <field name="name">春</field>
  <field name="value">花粉症,花</field>
  <field name="is_public">true</field>
</doc>
<doc>
  <field name="id">2</field>
  <field name="name">夏</field>
  <field name="value">暑い,海</field>
  <field name="is_public">true</field>
</doc>
<doc>
  <field name="id">3</field>
  <field name="name">秋</field>
  <field name="value">紅葉</field>
  <field name="is_public">true</field>
</doc>
<doc>
  <field name="id">4</field>
  <field name="name">冬</field>
  <field name="value">寒い,雪</field>
  <field name="is_public">true</field>
</doc>
</add>

あまり良いサンプルデータとはいえない。

■起動

cd example
java -jar start.jar

■データの登録

以下のコマンドでデータを登録する。

java -jar example/exampledocs/post.jar example/exampledocs/mydata.xml

■遊ぶ

http://localhost:8983/solr/admin/にアクセスする。

■データの削除

solrを止めてから以下のコマンドを実行する。

rm -fr example/solr/data/index

順序を間違えると面倒な事になる。

参考

■nginxをたてる

リモートにsolrを立てる場合は何らかの認証をしたいのでnginxを使ってBasic認証してみる。

wget http://dl.fedoraproject.org/pub/epel/5/x86_64/epel-release-5-4.noarch.rpm
rpm -ivh epel-release-5-4.noarch.rpm
yum install nginx
/sbin/chkconfig nginx on
/sbin/chkconfig --list nginx

nginxの設定

vim /etc/nginx/nginx.conf

以下のように記述する

location / {
    proxy_pass http://127.0.0.1:8389;
    auth_basic "Type your ID and password";
    auth_basic_user_file htpasswd;
}
yum install httpd
htpasswd -c /etc/nginx/htpasswd hoge
/etc/init.d/nginx restart

参考

■起動

再起動時にsolrが起動するようにする。

vim ~/start.sh
#!/bin/bash

cd /home/hoge/apache-solr-3.6.0/example
nohup java -jar /home/hoge/apache-solr-3.6.0/example/start.jar > /home/hoge/log/solr.log &
chmod 0777 start.sh

スクリプトが起動時に実行されるようにする。

sudo crontab -e
@reboot /home/ec2-user/start.sh

参考