SolrCellを使ったドキュメントインデクシング

# はじめに

* Solrを使ってPDFなどのドキュメントをインデクシングする要件があるとのことで、手順についてまとめておきます。
* ドキュメントのインデクシングではApacheTikaを取り込んで実装されたSolrCellを利用しています。
* ApacheTikaは節操ないくらい色々なものがパースできます。具体的にはPDFだけではなく、Word、Excel、HTML、画像、動画、圧縮されたファイル、クラスファイルなど色々なものがサポートされています。詳細については[こちら](https://tika.apache.org/1.5/formats.html)を読んでみてください。

# ドキュメントを読み込む前の設定

## SolrConfig.xml

* SolrConfig.xmlでsolr.extraction.ExtractingRequestHandlerが有効になっていることを確認します。
* uprefixとは、取得できたフィールド名の中でschema.xmlのフィールド定義にないものの先頭に付与する文字列を表しています。（後述するschema.xmlの定義と関連があります）
* fmap.xxxとはxxxというフィールド名をschema.xmlで定義されたフィールドの何にマッピングするかを定義しています。
* この場合、contentはdoctextというフィールド名にマッピングしています。

``` SolrConfig.xml
  <requestHandler name="/update/extract" 
                  startup="lazy"
                  class="solr.extraction.ExtractingRequestHandler" >
    <lst name="defaults">
      <str name="lowernames">true</str>
      <str name="uprefix">ignored_</str>

      <!-- capture link hrefs but ignore div attributes -->
      <str name="captureAttr">true</str>
      <str name="fmap.a">links</str>
      <str name="fmap.content">doctext</str>
      <str name="fmap.div">ignored_</str>
    </lst>
  </requestHandler>
```

## schema.xml

* solrconfig.xmlで必要となったignored_をダイナミックフィールドとして定義しています。
* ignored_フィールドは、インデクシングしたくないので、fieldtypeで保存もインデクシングもしないように定義しておきます。
* 全文検索されたフィールドはdoctextに入れます。

```schema.xml
<dynamicField name="ignored_*" type="ignored" multiValued="true"/>
<field name="doctext" type="text_ja" indexed="false" stored="true" multiValued="true"/>
・・・
<fieldtype name="ignored" stored="false" indexed="false" multiValued="true" class="solr.StrField" /
```

* 余談ですがドキュメントではない他のフィールドと合わせて全文検索させたい場合は、copyFieldの設定なども合わせてしておきます。

```
<copyField source="doctext" dest="text"/>
```

# SolrJで取り込んでみます。

* [Solrのリファレンスガイド](https://archive.apache.org/dist/lucene/solr/ref-guide/apache-solr-ref-guide-4.10.pdf)を取り込んでみます。
* なんてことはないコードなので説明は省きます。

```pom.xml
        <dependencies>
			<dependency>
				<groupId>org.apache.solr</groupId>
				<artifactId>solr-solrj</artifactId>
				<version>4.10.3</version>
			</dependency>
			<dependency>
				<groupId>commons-logging</groupId>
				<artifactId>commons-logging</artifactId>
				<version>1.1.1</version>
			</dependency>
        </dependencies>
```

```Pdf.java

import org.apache.solr.client.solrj.SolrServer;
import org.apache.solr.client.solrj.impl.HttpSolrServer;
import org.apache.solr.client.solrj.request.AbstractUpdateRequest;
import org.apache.solr.client.solrj.request.ContentStreamUpdateRequest;
import org.apache.solr.common.util.NamedList;

public class Pdf {

	public static void main(String... args) throws Exception {
		final SolrServer solr = new HttpSolrServer(
				"http://10.0.0.172:8983/solr/dora");
		final ContentStreamUpdateRequest update = new ContentStreamUpdateRequest(
				"/update/extract");
		update.addFile(new File(
				"/Users/yuzuru/Documents/work/apache-solr-ref-guide-4.10.pdf"),
				"application/pdf");
		update.setParam("literal.id", "apache-solr-ref-guide-4.10.pdf");

		update.setAction(AbstractUpdateRequest.ACTION.COMMIT, true, true);
		NamedList<Object> named = solr.request(update);
		System.out.println("finish" + named);
	}
}

```

# その他抑えておきたいこと

* curlで実行できるオプションはSolrJでももちろん指定できます。

## 解析だけさせることができます。

* parameterにextractOnly=trueを付与します。

```
update.setParam("extractOnly", "true");
```

* するとこんな感じで解析した結果が取れます。

```
<p/>
</div>
<div class="page">

<p/>
<p>483Apache Solr Reference Guide 4.10
</p>
<p>&lt;requestHandler name="/replication" class="solr.ReplicationHandler" &gt;
    &lt;lst name="slave"&gt;
</p>
以下略
```

## 解析した結果とれるフィールド名を知りたい。

contentというフィールドは確実に入ってきますが、それ以外に取れるフィールドを知りたいですよね。下記のようにインデクシングする必要はありませんが、勉強がてらインデクシングしてみます。

1.ダイナミックフィールドs_*を指定しておきます。

```
<dynamicField name="s_*" type="string" indexed="true" stored="true" multiValued="true"/>
```
2.uprefixにs_を指定して実行します。

```
update.setParam("uprefix", "s_");
```

3. solrのqueryを実行してみると色々取得できていることがわかります。

```
        "id": "apache-solr-ref-guide-4.10.pdf",
        "s_meta_creation_date": [
          "2014-09-02T21:24:47Z"
        ],
        "s_dcterms_modified": [
          "2014-09-02T21:24:47Z"
        ],
        "s_meta_save_date": [
          "2014-09-02T21:24:47Z"
        ],
        "s_dcterms_created": [
          "2014-09-02T21:24:47Z"
        ],
        "s_last_modified": [
          "2014-09-02T21:24:47Z"
        ],
        "s_date": [
          "2014-09-02T21:24:47Z"
        ],
        "s_modified": [
          "2014-09-02T21:24:47Z"
        ],
        "s_xmptpg_npages": [
          "511"
        ],
        "s_creation_date": [
          "2014-09-02T21:24:47Z"
        ],
```

# 参考URL

* [ExtractingRequestHandler](https://wiki.apache.org/solr/ExtractingRequestHandler)
* [Uploading Data with Solr Cell using Apache Tika](https://cwiki.apache.org/confluence/display/solr/Uploading+Data+with+Solr+Cell+using+Apache+Tika)