Apache Solr で全文検索

第2回 インデックスの追加/削除

2013.02.20

Solrへのインデックスの追加/削除などの操作は、XMLやJSONなどのフォーマットのドキュメントをSolrサーバにHTTP POSTすることで行います。

Solrがサポートしているフォーマットには次のものがあります。

  • XML
  • JSON
  • CSV

他にDataImportHandlerを使うことで、リレーショナルDBからSolrにインデックスを追加することやPDFなどからインデックスを追加することもできるようです。

今回はXMLでのインデックスの追加/削除の方法について説明したいと思います。

2.1 インデックスの追加方法

インデックスを追加するにはaddコマンドを送信します。addコマンドのXMLフォーマットは次のようになります。

<add>
  <doc>
    <field name="フィールド名">テキスト</field>
    [<field name="...">...</field>]
  </doc>
  [<doc> ... </doc>[<doc> ... </doc>]]
</add>

doc要素にインデックス化するドキュメントを指定します。ドキュメントにどのようなフィールドが含まれるかはスキーマ(schema.xml)で定義します。スキーマについては今後説明します。

add要素内に複数のdoc要素を指定できるので、一回のリクエストで複数のドキュメントを登録することができます。

field要素のname属性に登録するフィールドの名前を指定し、field要素の値に登録するテキストを指定します。

Solrに付属しているサンプル books.json(example/exampledocs/books.json) は XML形式では用意されていないようなので、これをXMLフォーマットに直して登録してみたいと思います。

books.jsonの最初のエントリをXMLフォーマットで表すと以下のようになります。

<add>
  <doc>
    <field name="id">978-0641723445</field>
    <field name="cat">book</field>
    <field name="cat">hardcover</field>
    <field name="name">The Lightning Thief</field>
    <field name="author">Rick Riordan</field>
    <field name="series_t">Percy Jackson and the Olympians</field>
    <field name="sequence_i">1</field>
    <field name="genre_s">fantasy</field>
    <field name="inStock">true</field>
    <field name="price">12.50</field>
    <field name="pages_i">384</field>
  </doc>
</add>

上記の内容をbooks.xmlというファイルに保存し、curlコマンドを使って登録してみます。なお、サーバの構成は前回のものと同様とします。

$ curl 'http://localhost:8080/solr/collection1/update?indent=true' --data-binary @books.xml -H 'Content-Type: text/xml'
<?xml version="1.0" encoding="UTF-8"?>
<response>
  <lst name="responseHeader">
    <int name="status">0</int>
    <int name="QTime">48</int>
  </lst>
</response>

コミット

addコマンドをリクエストしただけではまだ検索できません。ちゃんと検索できるようにするにはコミット処理が必要です。

コミットを行うには次の方法があります。

  • commitコマンドをPOSTする
  • URLにcommit=trueクエリパラメータをつけてGET/POSTする

commitコマンドの内容は以下の通りです。

<commit />

これをSolrサーバにPOSTします。

$ curl 'http://localhost:8080/solr/collection1/update?indent=true' --data-binary '<commit />' -H 'Content-Type: text/xml'
<?xml version="1.0" encoding="UTF-8"?>
<response>
  <lst name="responseHeader">
    <int name="status">0</int>
    <int name="QTime">8</int>
  </lst>
</response>

addコマンド送信時にcommit=trueクエリパラメータをつけることで、ドキュメントの登録とコミットを同時に行うこともできます。

$ curl 'http://localhost:8080/solr/collection1/update?commit=true&indent=true' --data-binary @books.xml -H 'Content-Type: text/xml'
<?xml version="1.0" encoding="UTF-8"?>
<response>
  <lst name="responseHeader">
    <int name="status">0</int>
    <int name="QTime">28</int>
  </lst>
</response>

これで検索できるようになりました。

$ curl 'http://localhost:8080/solr/collection1/select?q=Rick+Riordan&indent=true'
<?xml version="1.0" encoding="UTF-8"?>
<response>

<lst name="responseHeader">
  <int name="status">0</int>
  <int name="QTime">2</int>
  <lst name="params">
    <str name="indent">true</str>
    <str name="q">Rick Riordan</str>
    <str name="wt">xml</str>
  </lst>
</lst>
<result name="response" numFound="1" start="0">
  <doc>
    <str name="id">978-0641723445</str>
    <arr name="cat">
      <str>book</str>
      <str>hardcover</str>
    </arr>
    <str name="name">The Lightning Thief</str>
    <str name="author">Rick Riordan</str>
    <str name="author_s">Rick Riordan</str>
    <str name="series_t">Percy Jackson and the Olympians</str>
    <int name="sequence_i">1</int>
    <str name="genre_s">fantasy</str>
    <bool name="inStock">true</bool>
    <float name="price">12.5</float>
    <str name="price_c">12.50,USD</str>
    <int name="pages_i">384</int>
    <long name="_version_">1425014839691968512</long></doc>
</result>
</response>

2.2 インデックスの削除方法

登録したインデックスを削除するには、deleteコマンドを送信します。deleteコマンドのXMLフォーマットは次のようになります。

<delete>
  <id>ドキュメントID</id>
  [<id>...</id>]
  <query>検索クエリ</query>
  [<query>...</query>]
</delete>

検索するドキュメントはid要素かquery要素もしくは両方で指定します。また、id要素、query要素とも複数指定することができます。

<delete>
  <id>978-0641723445</id>
</delete>
<delete>
  <query>cat:book</query>
</delete>

id要素の値には、スキーマ定義の<uniqueKey>要素で指定したフィールドの値を指定します。サンプルでは”id”フィールドがこれにあたります。

なお、deleteコマンドも処理を完了するのにコミットが必要です。

それでは、先ほど登録したデータを削除してみます。以下の内容のファイルを delete.xml として保存します。

<delete>
  <id>978-0641723445</id>
</delete>

今度はcommit=trueパラメータもつけて、すぐ削除されるようにします。

$ curl 'http://localhost:8080/solr/collection1/update?commit=true&indent=true' --data-binary @delete.xml -H 'Content-Type: text/xml'
<?xml version="1.0" encoding="UTF-8"?>
<response>
  <lst name="responseHeader">
    <int name="status">0</int>
    <int name="QTime">124</int>
  </lst>
</response>

次に検索してみると。

$ curl 'http://localhost:8080/solr/collection1/select?q=Rick+Riordan&indent=true&wt=xml'
<?xml version="1.0" encoding="UTF-8"?>
<response>

<lst name="responseHeader">
  <int name="status">0</int>
  <int name="QTime">16</int>
  <lst name="params">
    <str name="indent">true</str>
    <str name="q">Rick Riordan</str>
    <str name="wt">xml</str>
  </lst>
</lst>
<result name="response" numFound="0" start="0">
</result>
</response>

となり、id=”978-0641723445”のドキュメントが削除されたことがわかります。

以上です。今回はインデックスの追加/削除方法について説明しました。

著者プロフィール

toza

ミドルウェアから上の層を色々とやってます。長春系八極拳使い。

記事一覧Index