SolrCloudのエイリアス機能(その1)

はじめに

SolrCloudにはコレクションにエイリアスを設定する機能があります。
このエイリアスが役に立つ場面として、リファレンスでは以下の3つが挙げられています。
・新しく作った、再生成したインデックスをダウンタイム無しで既存のものと差し替える
・コレクション名の変更がクライアントプラグラムに影響を与えないようにする
・同じスキーマの複数のコレクションに1回だけクエリを発行する

1つめと2つめについては経験がありますが、3つめの複数のコレクションを対象にエイリアスを設定するパターンは使ったことは無かったので、その挙動等を調べてみました。

複数コレクションにエイリアスを設定する

まずalias_test1とalias_test2の2つのコレクションを作成してエイリアスalias_testを設定。

$ curl -s 'http://localhost:8983/solr/admin/collections?action=CREATE&name=alias_test1&numShards=1&replicationFactor=1&wt=json'
$ curl -s 'http://localhost:8983/solr/admin/collections?action=CREATE&name=alias_test2&numShards=1&replicationFactor=1&wt=json'
$ curl -s 'http://localhost:8983/solr/admin/collections?action=CREATEALIAS&name=alias_test&collections=alias_test1,alias_test2'

エイリアスを確認。

curl -s 'http://localhost:8983/solr/admin/collections?action=CLUSTERSTATUS' | jq .cluster.aliases
{
  "alias_test1": "alias_test1",
  "alias_test2": "alias_test2",
  "alias_test": "alias_test1,alias_test2"
}

エイリアスに対するスキーマ変更

コレクションではなくエイリアスを指定してフィールドを追加してみます。

$ cat add_field.json
{
  "add-field":{
     "name":"date",
     "type":"pdate",
      "stored":true },
  "add-field":{
     "name":"body",
     "type":"string",
      "stored":true }
}
$ curl -s -X POST -H 'Content-type:application/json' -d @add_field.json 'http://localhost:8983/solr/alias_test/schema'

各コレクションのスキーマを確認。

$ curl -s 'http://localhost:8983/solr/alias_test1/schema/fields?omitHeader=true'
{
  "fields":[
    {
      "name":"_root_",
      "type":"string",
      "docValues":false,
      "indexed":true,
      "stored":false},
    {
      "name":"_text_",
      "type":"text_general",
      "multiValued":true,
      "indexed":true,
      "stored":false},
    {
      "name":"_version_",
      "type":"plong",
      "indexed":false,
      "stored":false},
    {
      "name":"body",
      "type":"string",
      "stored":true},
    {
      "name":"date",
      "type":"pdate",
      "stored":true},
    {
      "name":"id",
      "type":"string",
      "multiValued":false,
      "indexed":true,
      "required":true,
      "stored":true}]
$ curl -s 'http://localhost:8983/solr/alias_test2/schema/fields?omitHeader=true'
{
  "fields":[{
      "name":"_root_",
      "type":"string",
      "docValues":false,
      "indexed":true,
      "stored":false},
    {
      "name":"_text_",
      "type":"text_general",
      "multiValued":true,
      "indexed":true,
      "stored":false},
    {
      "name":"_version_",
      "type":"plong",
      "indexed":false,
      "stored":false},
    {
      "name":"id",
      "type":"string",
      "multiValued":false,
      "indexed":true,
      "required":true,
      "stored":true}]

dataフィールドとbodyフィールドが追加されたのはalias_test1の方だけでした。alias_test2にはコレクション名を指定してフィールドを追加しておきます。

$ curl -s -X POST -H 'Content-type:application/json' -d @add_field.json 'http://localhost:8983/solr/alias_test2/schema'
$ curl -s 'http://localhost:8983/solr/alias_test2/schema/fields?omitHeader=true'
{
  "fields":[{
      "name":"_root_",
      "type":"string",
      "docValues":false,
      "indexed":true,
      "stored":false},
    {
      "name":"_text_",
      "type":"text_general",
      "multiValued":true,
      "indexed":true,
      "stored":false},
    {
      "name":"_version_",
      "type":"plong",
      "indexed":false,
      "stored":false},
    {
      "name":"id",
      "type":"string",
      "multiValued":false,
      "indexed":true,
      "required":true,
      "stored":true},
    {
      "name":"body",
      "type":"string",
      "stored":true},
    {
      "name":"date",
      "type":"pdate",
      "stored":true}]

エイリアスに対する更新

エイリアス alias_test を指定してデータを投入してみます。

$ cat data.json
[
    {"id":"1",
     "date":"2019-01-01T00:00:00Z",
     "body":"body1"
    }
]
$ curl -s -X POST -H 'Content-type:application/json' -d @data.json 'http://localhost:8983/solr/alias_test/update/json/docs?commit=true'

それぞれのコレクションの内容を確認。

$ curl -s 'http://localhost:8983/solr/alias_test1/select?q=*%3A*&omitHeader=true'
{
  "response":{"numFound":1,"start":0,"docs":[
      {
        "id":"1",
        "date":"2019-01-01T00:00:00Z",
        "body":"body1",
        "_version_":1653627228838166528}]
  }}
$ curl -s 'http://localhost:8983/solr/alias_test2/select?q=*%3A*&omitHeader=true'
{
  "response":{"numFound":0,"start":0,"docs":[]
  }}

やはりalias_test1の方だけ更新されている。

エイリアスに対する検索

コレクションalias_test2を指定して別のデータを投入しておきます。

$ cat data2.json
[
    {"id":"2",
     "date":"2019-01-02T00:00:00Z",
     "body":"body2"
    }
]
$ curl -s -X POST -H 'Content-type:application/json' -d @data2.json 'http://localhost:8983/solr/alias_test2/update/json/docs?commit=true'
$ curl -s 'http://localhost:8983/solr/alias_test2/select?q=*%3A*&omitHeader=true'
{
  "response":{"numFound":1,"start":0,"docs":[
      {
        "id":"2",
        "date":"2019-01-02T00:00:00Z",
        "body":"body2",
        "_version_":1653898674683510784}]
  }}

エイリアスを指定して検索。

$ curl -s 'http://localhost:8983/solr/alias_test/select?q=*%3A*&omitHeader=true'
{
  "response":{"numFound":2,"start":0,"maxScore":1.0,"docs":[
      {
        "id":"1",
        "date":"2019-01-01T00:00:00Z",
        "body":"body1",
        "_version_":1653627228838166528},
      {
        "id":"2",
        "date":"2019-01-02T00:00:00Z",
        "body":"body2",
        "_version_":1653898674683510784}]
  }}

コレクション alias_test1 と alias_test2 の結果が統合されていることが分かります。

おわりに

複数のコレクションを対象にしたエイリアスの挙動を探ってみました。
検索では1回のリクエストで統一的に結果を得ることができます。
更新の場合は最初に指定されたコレクションがUPDATEリクエストを処理するようになっており、更新先を指定したい場合にはコレクション名を使う必要があります。

同じスキーマのコレクションを複数に分けたい使い方というのは、ログ等の時系列のデータが典型例です。実はSolrではこのような使い方に便利なRouted Aliasという機能が用意されています。Routed Aliasの詳細については別の機会に採り上げたいと思います。

コメント