LoginSignup
14

More than 5 years have passed since last update.

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

Last updated at Posted at 2015-03-30

はじめに

  • Solrを使ってPDFなどのドキュメントをインデクシングする要件があるとのことで、手順についてまとめておきます。
  • ドキュメントのインデクシングではApacheTikaを取り込んで実装されたSolrCellを利用しています。
  • ApacheTikaは節操ないくらい色々なものがパースできます。具体的にはPDFだけではなく、Word、Excel、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で取り込んでみます。

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_");
  1. 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

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
14