7.3.12. column_create#

7.3.12.1. 概要#

column_create はテーブルに新しいカラムを作成します。

1つのレコードに複数の値を保存したい場合は1つ以上カラムを作成する必要があります。

Groongaはインデックスをカラムとして提供しています。これは他のシステムと異なります。他のシステムではインデックスはインデックスです。インデックスをカラムとして実装していることで高い柔軟性を実現しています。たとえば、各トークンにメタデータを追加することができます。

カラムの詳細は カラム を見てください。

7.3.12.2. 構文#

このコマンドにはたくさんの引数があります。

多くの引数は必須です:

column_create table
              name
              flags
              type
              [source=null]
              [path=null]

7.3.12.3. 使い方#

このセクションでは次のことについて説明します。

以下は People テーブルの定義です。例ではこの People テーブルを使います。

実行例:

table_create \
  --name People \
  --flags TABLE_HASH_KEY \
  --key_type ShortText
# [[0,1337566253.89858,0.000355720520019531],true]

7.3.12.3.1. スカラーカラムを作成#

Groongaは1つの値を保存する用途としてスカラーカラムを提供しています。たとえば、「人」レコードに「年齢」情報を保存するときはスカラーカラムが適切です。なぜなら「人」レコードは「年齢」を1つだけ持つからです。

1つのレコードに複数の値を保存したい場合には、スカラーカラムは適していません。代わりに ベクターカラムを作成 を使ってください。

スカラーカラムを作成するには flags 引数に COLUMN_SCALAR を指定します。

以下は People テーブルに age カラムを作成する例です。 age カラムはスカラーカラムです。このカラムには UInt80-255 )の値を1つ保存できます。

実行例:

column_create \
  --table People \
  --name age \
  --flags COLUMN_SCALAR \
  --type UInt8
# [[0,1337566253.89858,0.000355720520019531],true]

以下の load コマンドで1つの値( 7 )を保存できます。

実行例:

load --table People
[
{"_key": "alice", "age": 7}
]
# [[0,1337566253.89858,0.000355720520019531],1]

以下の select コマンドで保存された1つの値( 7 )を確認できます。

実行例:

select --table People
# [
#   [
#     0,
#     1337566253.89858,
#     0.000355720520019531
#   ],
#   [
#     [
#       [
#         1
#       ],
#       [
#         [
#           "_id",
#           "UInt32"
#         ],
#         [
#           "_key",
#           "ShortText"
#         ],
#         [
#           "age",
#           "UInt8"
#         ]
#       ],
#       [
#         1,
#         "alice",
#         7
#       ]
#     ]
#   ]
# ]

7.3.12.3.2. ベクターカラムを作成#

Groongaは複数の値を保存する用途としてベクターカラムを提供しています。たとえば、「人」レコードに複数の「役割」を保存する場合はベクターカラムが適切です。なぜなら「人」レコードは複数の「役割」を持つかもしれないからです。

もし1つのレコードに値を1つだけ保存したい場合はベクターカラムは向いていません。代わりに スカラーカラムを作成 を使ってください。

ベクターカラムを作成するには flags パラメーターに COLUMN_VECTOR を指定します。

以下は People テーブルに roles カラムを作成する例です。 roles カラムはベクターカラムです。カラムの値として0個以上の ShortText の値を保存できます。

実行例:

column_create \
  --table People \
  --name roles \
  --flags COLUMN_VECTOR \
  --type ShortText
# [[0,1337566253.89858,0.000355720520019531],true]

以下の load コマンドで複数の値( ["adventurer", "younger-sister"] )を保存できます。

実行例:

load --table People
[
{"_key": "alice", "roles": ["adventurer", "younger-sister"]}
]
# [[0,1337566253.89858,0.000355720520019531],1]

保存した複数の値( ["adventurer", "younger-sister"] )は以下の select コマンドで確認できます。

実行例:

select --table People
# [
#   [
#     0,
#     1337566253.89858,
#     0.000355720520019531
#   ],
#   [
#     [
#       [
#         1
#       ],
#       [
#         [
#           "_id",
#           "UInt32"
#         ],
#         [
#           "_key",
#           "ShortText"
#         ],
#         [
#           "age",
#           "UInt8"
#         ],
#         [
#           "roles",
#           "ShortText"
#         ]
#       ],
#       [
#         1,
#         "alice",
#         7,
#         [
#           "adventurer",
#           "younger-sister"
#         ]
#       ]
#     ]
#   ]
# ]

7.3.12.3.3. 重み付きベクターカラムの作成#

TODO: See also 重み付きベクターカラム and adjuster.

7.3.12.3.4. テーブルのレコードを参照するカラムを作成#

スカラーカラムもベクターカラムも既存のテーブルのレコードへの参照を保存することができます。これはレコード間の参照関係を保存する場合に便利です。

たとえば、「本」レコードで登場人物を保存する場合は、「人」レコードを参照するカラムを使うとよいです。なぜなら、同じ「人」が複数の本に登場するかもしれないからです。

テーブルのレコードを参照するカラムを作成するには type パラメーターに参照するテーブルの名前を指定します。

以下は Books テーブルに character カラムを作成する例です。 character カラムは People テーブルを参照しています。 character カラムには People テーブルのレコードを1つ保存できます。

以下が Books テーブルの定義です。

実行例:

table_create \
  --name Books \
  --flags TABLE_HASH_KEY \
  --key_type ShortText
# [[0,1337566253.89858,0.000355720520019531],true]

以下は Books テーブルにある character カラムの定義です。 --type People がポイントです。

実行例:

column_create \
  --table Books \
  --name character \
  --flags COLUMN_SCALAR \
  --type People
# [[0,1337566253.89858,0.000355720520019531],true]

以下の load コマンドで1つの参照( "alice" )を保存できます。レコードを参照するにはキーの値( People._key の値)を使います。

実行例:

load --table Books
[
{"_key": "Alice's Adventure in Wonderland", "character": "alice"}
]
# [[0,1337566253.89858,0.000355720520019531],1]

保存した参照( "alice" レコード)は以下の select コマンドで確認できます。以下の例では age カラムの値と roles カラムの値を取得しています。

実行例:

select \
 --table Books \
 --output_columns _key,character._key,character.age,character.roles
# [
#   [
#     0,
#     1337566253.89858,
#     0.000355720520019531
#   ],
#   [
#     [
#       [
#         1
#       ],
#       [
#         [
#           "_key",
#           "ShortText"
#         ],
#         [
#           "character._key",
#           "ShortText"
#         ],
#         [
#           "character.age",
#           "UInt8"
#         ],
#         [
#           "character.roles",
#           "ShortText"
#         ]
#       ],
#       [
#         "Alice's Adventure in Wonderland",
#         "alice",
#         7,
#         [
#           "adventurer",
#           "younger-sister"
#         ]
#       ]
#     ]
#   ]
# ]

7.3.12.3.5. インデックスカラムを作成#

Groongaは高速に検索する用途としてインデックスカラムを提供しています。インデックスカラムはあなたのデータを保存しません。インデックスカラムは高速な検索に必要なデータを保存します。

インデックスカラムは自分で更新する必要はありません。インデックス対象のデータカラム(スカラーカラムまたはベクターカラム)にデータを入れると、インデックスカラムは自動で更新されます。1つのインデックスカラムに複数のインデックス対象のカラムを指定することもできます。

新規にインデックスを作成する場合、インデックスの構築が完了するまで、そのインデックスは無視されます。

もし、 People テーブルの age カラム用のインデックスカラムがあると、 age カラムの値に対する完全一致検索・比較検索・範囲検索を高速に処理することができます。

インデックスカラムを作成するには次のパラメーターを指定します。

  • flags パラメーター: COLUMN_INDEX

  • type パラメーター: インデックス対象カラムのテーブル名(たとえば People

  • source パラメーター:インデックス対象カラム名(たとえば age

完全一致検索・比較検索・範囲検索用のインデックスカラムには flags パラメーターに追加のフラグは必要ありません。全文検索用のインデックスカラム、マルチカラムインデックスカラムには追加のフラグが必要になります。詳細は 全文検索用のインデックスカラムを作成マルチカラムインデックスカラムを作成 を見てください。

以下は People テーブルの age カラム用のインデックスカラムを作成する例です。

はじめに範囲インデックスカラム用のテーブルを作成します。詳細は 範囲検索用のインデックステーブルの作成 を見てください。この例では TABLE_PAT_KEY として Ages テーブルを作成します。

実行例:

table_create \
  --name Ages \
  --flags TABLE_PAT_KEY \
  --key_type UInt8
# [[0,1337566253.89858,0.000355720520019531],true]

これで People テーブルの age カラム用のインデックスカラムを作れるようになりました。 flags パラメーターの COLUMN_INDEXtype パラメーターの Peoplesource パラメーターの age がポイントです。

実行例:

column_create \
  --table Ages \
  --name people_age_index \
  --flags COLUMN_INDEX \
  --type People \
  --source age
# [[0,1337566253.89858,0.000355720520019531],true]

ログを確認すると、新しく作成した Ages.people_age_index インデックスカラムを使って age > 5 を評価していることがわかります。Groongaは使用したインデックスカラムを info ログレベルでログに出力します。ログレベルは log_level コマンドを使うと動的に変更できます。

実行例:

log_level --level info
# [[0,1337566253.89858,0.000355720520019531],true]
select \
  --table People \
  --filter 'age > 5'
# [
#   [
#     0,
#     1337566253.89858,
#     0.000355720520019531
#   ],
#   [
#     [
#       [
#         1
#       ],
#       [
#         [
#           "_id",
#           "UInt32"
#         ],
#         [
#           "_key",
#           "ShortText"
#         ],
#         [
#           "age",
#           "UInt8"
#         ],
#         [
#           "roles",
#           "ShortText"
#         ]
#       ],
#       [
#         1,
#         "alice",
#         7,
#         [
#           "adventurer",
#           "younger-sister"
#         ]
#       ]
#     ]
#   ]
# ]
# log: 2023-10-05 17:26:13.890356|i| [table-selector][select][index][range] <Ages.people_age_index>
log_level --level notice
# [[0,1337566253.89858,0.000355720520019531],true]

以下のログから Ages.people_age_index が使われたことを確認できます。

[table][select][index][range] <Ages.people_age_index>

このログは範囲検索に Ages.people_age_index インデックスカラムを使ったことを示しています。

7.3.12.3.7. マルチカラムインデックスカラムを作成#

複数のカラム用のインデックスカラムを作成できます。これは1つのインデックスカラムで複数のカラムに対して高速に検索できるということです。インデックス対象の複数のカラムが多くの同じトークンを共有しているときは、マルチカラムインデックスカラムはシングルカラムインデックスカラムよりも空間効率がよくなります。一方、検索速度はシングルカラムインデックスカラムの方が速くなることが多いです。理由はマルチカラムインデックスカラムは大きくなりがちだからです。

1つのマルチカラムインデックスカラムで、異なるテーブルの複数のカラムをインデックス対象にすることはできません。1つのマルチカラムインデックスカラムでは同じテーブルの複数のカラムをインデックス対象に指定してください。たとえば、 People._keyBooks._key をインデックス対象としたマルチカラムインデックスカラムは作成できません。なぜなら、違うテーブルのカラムだからです。 People._keyPeople.roles をインデックス対象としたマルチカラムインデックスカラムは作成できます。なぜなら同じテーブルのカラムだからです。

シングルカラムインデックスカラムとマルチカラムインデックスカラムでは違いがあります。マルチカラムインデックスカラムのときは flags パラメーターに WITH_SECTION を追加しなければいけません。つまり、 flags パラメーターに COLUMN_INDEX|WITH_SECTION と指定するということです。これが違いです。

全文検索用のマルチカラムインデックスカラムを作成する場合は flags パラメーターに COLUMN_INDEX|WITH_POSITION|WITH_SECTION と指定します。全文検索インデックスカラムの詳細は 全文検索用のインデックスカラムを作成 を見てください。

以下は People テーブルのキーと roles カラム用のマルチカラムインデックスカラムを作成する例です。

インデックス用のテーブルは、シングルカラムインデックスとマルチカラムインデックスカラムで違いはありません。

この例では、完全一致検索と前方一致検索用に Names テーブルを作りました。このテーブルは TABLE_PAT_KEY を使っています。なぜなら TABLE_PAT_KEY は前方一致検索をサポートしているからです。詳細は テーブル を参照してください。

実行例:

table_create \
  --name Names \
  --flags TABLE_PAT_KEY \
  --key_type ShortText \
  --normalizer NormalizerAuto
# [[0,1337566253.89858,0.000355720520019531],true]

People テーブルのキーと roles カラム用のマルチカラムインデックスカラムを作成します。 flags パラメーターの COLUMN_INDEX|WITH_SECTIONtype パラメーターの Peoplesource パラメーターの _key,roles がポイントです。

実行例:

column_create \
  --table Names \
  --name people_key_roles_index \
  --flags COLUMN_INDEX|WITH_SECTION \
  --type People \
  --source _key,roles
# [[0,1337566253.89858,0.000355720520019531],true]

ログを確認すると、新しく作成した Names.people_key_roles_index インデックスカラムを使って --filter 'roles @^ "Younger" を評価していることがわかります。Groongaは使用したインデックスカラムを info ログレベルでログに出力します。ログレベルは log_level コマンドを使うと動的に変更できます。

実行例:

log_level --level info
# [[0,1337566253.89858,0.000355720520019531],true]
select \
  --table People \
  --filter 'roles @^ "Younger"'
# [
#   [
#     0,
#     1337566253.89858,
#     0.000355720520019531
#   ],
#   [
#     [
#       [
#         1
#       ],
#       [
#         [
#           "_id",
#           "UInt32"
#         ],
#         [
#           "_key",
#           "ShortText"
#         ],
#         [
#           "age",
#           "UInt8"
#         ],
#         [
#           "roles",
#           "ShortText"
#         ]
#       ],
#       [
#         1,
#         "alice",
#         7,
#         [
#           "adventurer",
#           "younger-sister"
#         ]
#       ]
#     ]
#   ]
# ]
# log: 2023-10-05 17:26:13.890356|i| [table-selector][select][index][prefix] <Names.people_key_roles_index>
log_level --level notice
# [[0,1337566253.89858,0.000355720520019531],true]

以下のログから Names.people_key_roles_index を使ったことを確認できます。

[table][select][index][prefix] <Names.people_key_roles_index>

このログは前方一致検索に Names.people_key_roles_index インデックスカラムを使ったことを示しています。

7.3.12.3.8. 小さなインデックスカラムを作成#

もし、インデックス対象のデータが小さいことがわかっているならインデックスカラムが使用するメモリー量を減らせます。デフォルトのインデックスカラムと比べて 1/256 のメモリー使用量になります。

ではどのくらいのデータなら小さいのでしょうか。それはデータによります。小さなインデックスカラムは少なくとも10億レコードを扱えません。もし、インデックス対象がテキスト系の型(ShortTextTextLongText のどれか)ではないスカラーカラムだけの場合、扱える最大レコード数はインデックス対象のデータの種類に依存します。もし、インデックス対象のカラムに 1123 というデータが入っていたとすると、種類数は 3123 )になります。以下の表はインデックス対象データの種類数と扱える最大レコード数の関係を示しています。

インデックス対象データの種類数と小さなインデックスカラムで扱えるレコード数#

インデックス対象のデータの種類数

処理できるレコード数

1

16779234

2

4648070

4

7238996

8

8308622

16

11068624

32

12670817

64

18524211

128

38095511

256

51265384

小さなインデックスカラムを作成するには COLUMN_INDEX|INDEX_SMALL というように flags パラメーターに INDEX_SMALL を追加します。

People テーブルが100万レコードしかないなら、 age カラム用に小さなインデックスカラムを使うことができます。

実行例:

column_create \
  --table Ages \
  --name people_age_small_index \
  --flags COLUMN_INDEX|INDEX_SMALL \
  --type People \
  --source age
# [[0,1337566253.89858,0.000355720520019531],true]

7.3.12.3.9. 中サイズのインデックスカラムを作成#

インデックス対象のデータが中サイズならインデックスカラムが使うメモリー使用量を減らすことができます。デフォルトのインデックスカラムよりも 5/24 のメモリー使用量になります。

どのくらいのデータが中サイズのデータでしょうか。それはデータによります。

もし、インデックス対象がスカラーカラム1つだけであれば、中サイズのインデックスカラムはすべてのレコードを処理できます。

以下のケースでは中サイズのインデックスカラムはすべてのレコードを処理できないかもしれません。

  • インデックス対象がテキスト系の型( ShortTextTextLongText のどれか)のスカラーカラム1つ

  • インデックス対象がベクターカラム1つ

  • インデックス対象が複数のカラム

  • インデックステーブルにトークナイザーが付いている

中サイズのインデックスカラムを作成するには COLUMN_INDEX|INDEX_MEDIUM というように flags パラメーターに INDEX_MEDIUM を追加します。

People テーブルの age カラム用のインデックスカラムであれば中サイズのインデックスカラムでも安全です。なぜなら、 UInt8 型のスカラーカラム1つだからです。

以下は中サイズのインデックスカラムを作る例です。

実行例:

column_create \
  --table Ages \
  --name people_age_medium_index \
  --flags COLUMN_INDEX|INDEX_MEDIUM \
  --type People \
  --source age
# [[0,1337566253.89858,0.000355720520019531],true]

7.3.12.3.10. 大きなインデックスカラムを作成#

もし、インデックス対象のデータが大きいことがわかっているなら大きなインデックスカラムを使わなければいけません。このインデックスカラムが使用するメモリー量が増えますが、より多くのデータを扱えます。デフォルトのインデックスカラムと比べて2倍のメモリー使用量になります。

どのくらいのデータが大きなデータでしょうか。それはデータによります。

もし、インデックス対象がスカラーカラム1つだけであれば、大きくありません。

大きなデータは大量のレコード(通常は少なくとも1000万レコード以上)があり、少なくとも次のうちの1つ以上の特徴があります。

  • インデックス対象が複数のカラム

  • インデックステーブルにトークナイザーが付いている

大きなインデックスカラムを作成するには COLUMN_INDEX|INDEX_LARGE というように flags パラメーターに INDEX_LARGE を追加します。

以下は People テーブルのキーと roles カラム用に大きなインデックスカラムを作成する例です。

以下は大きなインデックスカラムを作る例です。

実行例:

column_create \
  --table Terms \
  --name people_roles_large_index \
  --flags COLUMN_INDEX|WITH_POSITION|WITH_SECTION|INDEX_LARGE \
  --type People \
  --source roles
# [[0,1337566253.89858,0.000355720520019531],true]

7.3.12.3.11. ミッシングモード#

バージョン 12.0.2 で追加.

MISSING_* フラグを使うと参照カラムに指定した新しい値に存在しないキーがあったときにどう処理するかを制御できます。指定できる MISSING_* フラグは次のとおりです。

  • MISSING_ADD (デフォルト)

  • MISSING_IGNORE

  • MISSING_NIL

1つのカラムに複数の MISSING_* フラグを指定することはできません。

MISSING_* フラグは参照カラムでのみ意味があります。

次の表は参照スカラーカラムに存在しないキーを指定したときに MISSING_* フラグでどのような違いがあるかを説明しています。

フラグ

説明

指定された値の例

セットされた値の例

MISSING_ADD

指定された存在しないキーは参照されているテーブルに自動で追加されます。新しく追加されたレコードのIDが値としてセットされます。

これがデフォルトです。

"nonexistent"

キーの値が "nonexistent" の新しく追加されたレコードのID。

MISSING_IGNORE

指定された存在しないキーは無視され、 0 がセットされます。

参照スカラーカラムでは MISSING_IGNOREMISSING_NIL に違いはありません。

"nonexistent"

0

MISSING_NIL

指定された存在しないキーは無視され、 0 がセットされます。

参照スカラーカラムでは MISSING_IGNOREMISSING_NIL に違いはありません。

"nonexistent"

0

次の例は参照スカラーカラムが MISSING_* フラグでどう変わるかを示す例です。

最初に、この例ではすべての MISSING_* フラグ用のカラムをそれぞれ定義します。

実行例:

table_create \
  --name MissingModeScalarReferred \
  --flags TABLE_HASH_KEY \
  --key_type ShortText
# [[0,1337566253.89858,0.000355720520019531],true]
table_create \
  --name MissingModeScalar \
  --flags TABLE_HASH_KEY \
  --key_type ShortText
# [[0,1337566253.89858,0.000355720520019531],true]
column_create \
  --table MissingModeScalar \
  --name missing_add \
  --flags COLUMN_SCALAR|MISSING_ADD \
  --type MissingModeScalarReferred
# [[0,1337566253.89858,0.000355720520019531],true]
column_create \
  --table MissingModeScalar \
  --name missing_ignore \
  --flags COLUMN_SCALAR|MISSING_IGNORE \
  --type MissingModeScalarReferred
# [[0,1337566253.89858,0.000355720520019531],true]
column_create \
  --table MissingModeScalar \
  --name missing_nil \
  --flags COLUMN_SCALAR|MISSING_NIL \
  --type MissingModeScalarReferred
# [[0,1337566253.89858,0.000355720520019531],true]

それから、この例では存在しないキーをすべてのカラムにロードします。 MISSING_ADD 付きのカラムに指定した存在しないキーだけが自動的に MissingModeScalarReferred に追加されます。 MISSING_IGNOREMISSING_NIL 付きのカラムに指定した存在しないキーは MissingModeScalarReferred に追加されません。 missing_ignore の値と missing_nil の値は "" と表示されます。なぜなら、これらのカラムの値はIDが 0 のレコードを参照しているからです。IDが 0 のレコードは必ず存在しないのでキーが存在しません。そのため、 "" と表示されます。

実行例:

load --table MissingModeScalar
[
{"_key": "key", "missing_add":    "nonexistent1"}
]
# [[0,1337566253.89858,0.000355720520019531],1]
load --table MissingModeScalar
[
{"_key": "key", "missing_ignore": "nonexistent2"}
]
# [
#   [
#     -22,
#     1337566253.89858,
#     0.000355720520019531,
#     "<MissingModeScalar.missing_ignore>: failed to cast to <MissingModeScalarReferred>: <\"nonexistent2\">",
#     [
#       [
#         "grn_ra_cast_value",
#         "lib/store.c",
#         522
#       ]
#     ]
#   ],
#   1
# ]
load --table MissingModeScalar
[
{"_key": "key", "missing_nil":    "nonexistent3"}
]
# [
#   [
#     -22,
#     1337566253.89858,
#     0.000355720520019531,
#     "<MissingModeScalar.missing_nil>: failed to cast to <MissingModeScalarReferred>: <\"nonexistent3\">",
#     [
#       [
#         "grn_ra_cast_value",
#         "lib/store.c",
#         522
#       ]
#     ]
#   ],
#   1
# ]
select --table MissingModeScalar
# [
#   [
#     0,
#     1337566253.89858,
#     0.000355720520019531
#   ],
#   [
#     [
#       [
#         1
#       ],
#       [
#         [
#           "_id",
#           "UInt32"
#         ],
#         [
#           "_key",
#           "ShortText"
#         ],
#         [
#           "missing_add",
#           "MissingModeScalarReferred"
#         ],
#         [
#           "missing_ignore",
#           "MissingModeScalarReferred"
#         ],
#         [
#           "missing_nil",
#           "MissingModeScalarReferred"
#         ]
#       ],
#       [
#         1,
#         "key",
#         "nonexistent1",
#         "",
#         ""
#       ]
#     ]
#   ]
# ]
select --table MissingModeScalarReferred
# [
#   [
#     0,
#     1337566253.89858,
#     0.000355720520019531
#   ],
#   [
#     [
#       [
#         1
#       ],
#       [
#         [
#           "_id",
#           "UInt32"
#         ],
#         [
#           "_key",
#           "ShortText"
#         ]
#       ],
#       [
#         1,
#         "nonexistent1"
#       ]
#     ]
#   ]
# ]

次の表は参照ベクターカラムに存在しないキーを含むベクターを指定したときに MISSING_* フラグでどのような違いがあるかを説明します。

フラグ

説明

指定された値の例

セットされた値の例

MISSING_ADD

指定された存在しないキーは参照されているテーブルに自動的に追加されます。その要素の値は新しく追加されたレコードのIDになります。

これがデフォルトです。

["existent1", "nonexistent", "existent2"]

"existent1""nonexistent""existent2" のレコードのIDです。

MISSING_IGNORE

指定された存在しないキーの要素は無視されます。

["existent1", "nonexistent", "existent2"]

"existent1""existent2" のレコードIDです。

MISSING_NIL

指定された存在しないキーの要素は無視されます。

INVALID_WARN あるいは INVALID_IGNORE も指定している場合は、この要素は 0 に置き換えられます。もし、 INVALID_ERROR を指定しているあるいはなにも INVALID_* を指定していない場合は、この要素は無視されます。

不正モード も参照してください。

["existent1", "nonexistent", "existent2"]

INVALID_WARNINVALID_IGNORE の場合は "existent1" のレコードIDと 0"existent2" のレコードIDです。

INVALID_ERROR を指定している場合となにも INVALID_* を指定していない場合は "existent1""existent2" のレコードIDです。

次の例は参照ベクターカラムに MISSING_* フラグを指定したときの違いを示しています。

最初に、この例ではすべての MISSING_* フラグ用のカラムをそれぞれ定義します。

実行例:

table_create \
  --name MissingModeVectorReferred \
  --flags TABLE_HASH_KEY \
  --key_type ShortText
# [[0,1337566253.89858,0.000355720520019531],true]
table_create \
  --name MissingModeVector \
  --flags TABLE_HASH_KEY \
  --key_type ShortText
# [[0,1337566253.89858,0.000355720520019531],true]
column_create \
  --table MissingModeVector \
  --name missing_add \
  --flags COLUMN_VECTOR|MISSING_ADD \
  --type MissingModeVectorReferred
# [[0,1337566253.89858,0.000355720520019531],true]
column_create \
  --table MissingModeVector \
  --name missing_ignore \
  --flags COLUMN_VECTOR|MISSING_IGNORE|INVALID_IGNORE \
  --type MissingModeVectorReferred
# [[0,1337566253.89858,0.000355720520019531],true]
column_create \
  --table MissingModeVector \
  --name missing_nil \
  --flags COLUMN_VECTOR|MISSING_NIL|INVALID_IGNORE \
  --type MissingModeVectorReferred
# [[0,1337566253.89858,0.000355720520019531],true]

それからこの例はすべてのカラムに存在しないキーを含むベクターを設定します。 MISSING_ADD を指定したカラムの場合だけ、存在しないキーは自動的に MissingModeVectorReferred に追加されます。 MISSING_IGNOREMISSING_NIL を指定したカラムの場合は MissingModeVectorReferred には追加されません。 missing_ignore の値では存在しないキーの要素は削除されます。 missing_nil の値では存在しないキーの要素は 0 に置き換えられます。なぜなら INVALID_IGNORE も指定されているからです。 0 に置き換えられた要素は "" と表示されます。なぜならこの要素はID 0 のレコードを参照することになるからです。IDが 0 のレコードは必ず存在しないのでキーが存在しません。そのため "" と表示されます。

実行例:

load --table MissingModeVectorReferred
[
{"_key": "existent1"},
{"_key": "existent2"}
]
# [[0,1337566253.89858,0.000355720520019531],2]
load --table MissingModeVector
[
{"_key": "key", "missing_add":    ["existent1", "nonexistent1", "existent2"]}
]
# [[0,1337566253.89858,0.000355720520019531],1]
load --table MissingModeVector
[
{"_key": "key", "missing_ignore": ["existent1", "nonexistent2", "existent2"]}
]
# [[0,1337566253.89858,0.000355720520019531],1]
load --table MissingModeVector
[
{"_key": "key", "missing_nil":    ["existent1", "nonexistent3", "existent2"]}
]
# [[0,1337566253.89858,0.000355720520019531],1]
select --table MissingModeVector
# [
#   [
#     0,
#     1337566253.89858,
#     0.000355720520019531
#   ],
#   [
#     [
#       [
#         1
#       ],
#       [
#         [
#           "_id",
#           "UInt32"
#         ],
#         [
#           "_key",
#           "ShortText"
#         ],
#         [
#           "missing_add",
#           "MissingModeVectorReferred"
#         ],
#         [
#           "missing_ignore",
#           "MissingModeVectorReferred"
#         ],
#         [
#           "missing_nil",
#           "MissingModeVectorReferred"
#         ]
#       ],
#       [
#         1,
#         "key",
#         [
#           "existent1",
#           "nonexistent1",
#           "existent2"
#         ],
#         [
#           "existent1",
#           "existent2"
#         ],
#         [
#           "existent1",
#           "",
#           "existent2"
#         ]
#       ]
#     ]
#   ]
# ]
select --table MissingModeVectorReferred
# [
#   [
#     0,
#     1337566253.89858,
#     0.000355720520019531
#   ],
#   [
#     [
#       [
#         3
#       ],
#       [
#         [
#           "_id",
#           "UInt32"
#         ],
#         [
#           "_key",
#           "ShortText"
#         ]
#       ],
#       [
#         1,
#         "existent1"
#       ],
#       [
#         2,
#         "existent2"
#       ],
#       [
#         3,
#         "nonexistent1"
#       ]
#     ]
#   ]
# ]

7.3.12.3.12. 不正モード#

バージョン 12.0.2 で追加.

INVALID_* フラグを使うことでデータカラムに指定した新しい値に不正な値があったときにどう処理するかを制御できます。指定できる INVALID_* フラグは次のとおりです。

  • INVALID_ERROR (デフォルト)

  • INVALID_WARN

  • INVALID_IGNORE

1つのカラムに複数の INVALID_* フラグを指定することはできません。

INVALID_* フラグは COLUMN_SCALARCOLUMN_VECTOR でだけ使えます。

対象のカラムが参照カラムの場合、どんな値が不正かどうかは ミッシングモード に依ります。もし、 MISSING_IGNORE あるいは MISSING_NIL を指定している場合は存在しないキーは不正な値です。ただし、空文字列キーあるいはノーマライズするとから文字列になるキーはどの MISSING_* フラグの値でも不正ではありません。これらは特別です。

対象のカラムが参照カラムでない場合はどんな値が不正かどうかはカラムの値の型に依ります。たとえば、 Int32 スカラーカラムでは "invalid" は不正な値です。

次の表は Int32 スカラーカラムに不正な値を指定したときに INVALID_* フラグでどんな違いがあるかを説明します。

フラグ

説明

指定された値の例

セットされた値の例

INVALID_ERROR

指定された不正な値は プロセスログ にエラーとして記録され、 load もエラーを返します。

指定された不正な値はセットされません。

これがデフォルトです。

"invalid"

このカラムは更新されません。

INVALID_WARN

指定された不正な値は プロセスログ に警告として記録されます。

指定された不正な値は対象のスカラーカラムのデフォルト値に置き換えられます。たとえば、 Int32 スカラーカラムでは 0 がデフォルト値です。

"nonexistent"

0

INVALID_IGNORE

指定された不正な値はセットされません。

指定された不正な値は対象のスカラーカラムのデフォルト値に置き換えられます。たとえば、 Int32 スカラーカラムでは 0 がデフォルト値です。

"invalid"

0

次の例は Int32 スカラーカラムで INVALID_* のフラグでどんな違いがあるかを示します。

最初にこの例はすべての INVALID_* フラグ用のカラムをそれぞれ定義します。

実行例:

table_create \
  --name InvalidModeScalar \
  --flags TABLE_HASH_KEY \
  --key_type ShortText
# [[0,1337566253.89858,0.000355720520019531],true]
column_create \
  --table InvalidModeScalar \
  --name invalid_error \
  --flags COLUMN_SCALAR|INVALID_ERROR \
  --type Int32
# [[0,1337566253.89858,0.000355720520019531],true]
column_create \
  --table InvalidModeScalar \
  --name invalid_warn \
  --flags COLUMN_SCALAR|INVALID_WARN \
  --type Int32
# [[0,1337566253.89858,0.000355720520019531],true]
column_create \
  --table InvalidModeScalar \
  --name invalid_ignore \
  --flags COLUMN_SCALAR|INVALID_IGNORE \
  --type Int32
# [[0,1337566253.89858,0.000355720520019531],true]

それからこの例は初期値としてすべてのカラムに 29 をロードします。これは更新時でどのような違いがあるかを示すためです。

実行例:

load --table InvalidModeScalar
[
  {
    "_key": "key",
    "invalid_error":  29,
    "invalid_warn":   29,
    "invalid_ignore": 29
  }
]
# [[0,1337566253.89858,0.000355720520019531],1]
select \
  --table InvalidModeScalar \
  --output_columns invalid_error,invalid_warn,invalid_ignore
# [
#   [
#     0,
#     1337566253.89858,
#     0.000355720520019531
#   ],
#   [
#     [
#       [
#         1
#       ],
#       [
#         [
#           "invalid_error",
#           "Int32"
#         ],
#         [
#           "invalid_warn",
#           "Int32"
#         ],
#         [
#           "invalid_ignore",
#           "Int32"
#         ]
#       ],
#       [
#         29,
#         29,
#         29
#       ]
#     ]
#   ]
# ]

それからこの例は不正な値で既存のカラムの値を更新します。指定された不正な値は INVALID_ERROR のときだけ load はエラーを返します。そして INVALID_ERROR のときだけ既存の値は更新されません。 INVALID_WARNINVALID_IGNORE のときは既存の値は 0 で更新されます。この例では INVALID_WARNINVALID_IGNORE の違いはわかりませんが、 INVALID_WARN のときだけ プロセスログ に警告メッセージが記録されています。

実行例:

load --table InvalidModeScalar
[
{"_key": "key", "invalid_error":  "invalid"},
]
# [
#   [
#     -22,
#     1337566253.89858,
#     0.000355720520019531,
#     "<InvalidModeScalar.invalid_error>: failed to cast to <Int32>: <\"invalid\">",
#     [
#       [
#         "grn_ra_cast_value",
#         "lib/store.c",
#         522
#       ]
#     ]
#   ],
#   1
# ]
load --table InvalidModeScalar
[
{"_key": "key", "invalid_warn":   "invalid"},
]
# [[0,1337566253.89858,0.000355720520019531],1]
load --table InvalidModeScalar
[
{"_key": "key", "invalid_ignore": "invalid"},
]
# [[0,1337566253.89858,0.000355720520019531],1]
select \
  --table InvalidModeScalar \
  --output_columns invalid_error,invalid_warn,invalid_ignore
# [
#   [
#     0,
#     1337566253.89858,
#     0.000355720520019531
#   ],
#   [
#     [
#       [
#         1
#       ],
#       [
#         [
#           "invalid_error",
#           "Int32"
#         ],
#         [
#           "invalid_warn",
#           "Int32"
#         ],
#         [
#           "invalid_ignore",
#           "Int32"
#         ]
#       ],
#       [
#         29,
#         0,
#         0
#       ]
#     ]
#   ]
# ]

次の表は Int32 ベクターカラムに不正な要素を含むベクターを設定したときに INVALID_* フラグによってどのような違いがあるかを説明します。

フラグ

説明

指定された値の例

セットされた値の例

INVALID_ERROR

指定された不正な要素は プロセスログ にエラーとして記録されますが、 load はエラーを返しません。

もし対象のカラムが参照ベクターカラムで MISSING_NIL フラグが指定されていた場合は、不正な要素は 0 に置き換えられます。それ以外のフラグの場合は不正な要素は無視されます。

[1, "invalid", 3]

[1, 3]

INVALID_WARN

指定された不正な要素は プロセスログ に警告として記録されます。

もし対象のカラムが参照ベクターカラムで MISSING_NIL フラグが指定されていた場合は、不正な要素は 0 に置き換えられます。それ以外のフラグの場合は不正な要素は無視されます。

[1, "invalid", 3]

[1, 3]

INVALID_IGNORE

指定された不正な要素は無視されます。

もし対象のカラムが参照ベクターカラムで MISSING_NIL フラグが指定されていた場合は、不正な要素は 0 に置き換えられます。それ以外のフラグの場合は不正な要素は無視されます。

[1, "invalid", 3]

[1, 3]

次の例は参照ベクターカラムでは INVALID_* フラグでどのような違いがあるかを示します。

最初にこの例はすべての INVALID_* フラグ用のカラムをそれぞれ定義します。

実行例:

table_create \
  --name InvalidModeVector \
  --flags TABLE_HASH_KEY \
  --key_type ShortText
# [[0,1337566253.89858,0.000355720520019531],true]
column_create \
  --table InvalidModeVector \
  --name invalid_error \
  --flags COLUMN_VECTOR|INVALID_ERROR \
  --type Int32
# [[0,1337566253.89858,0.000355720520019531],true]
column_create \
  --table InvalidModeVector \
  --name invalid_warn \
  --flags COLUMN_VECTOR|INVALID_WARN \
  --type Int32
# [[0,1337566253.89858,0.000355720520019531],true]
column_create \
  --table InvalidModeVector \
  --name invalid_ignore \
  --flags COLUMN_VECTOR|INVALID_IGNORE \
  --type Int32
# [[0,1337566253.89858,0.000355720520019531],true]

それからこの例は不正な要素を含むベクターをすべてのカラムにロードします。すべての指定された不正な要素は INVALID_* フラグによらず無視されます。 プロセスログ 内のメッセージは INVALID_* フラグによって違います。 INVALID_ERROR を指定している場合は プロセスログ にエラーメッセージが記録されます。 INVALID_WARN を指定している場合は プロセスログ に警告メッセージが記録されます。 INVALID_IGNORE を指定している場合は プロセスログ にメッセージは記録されません。

実行例:

load --table InvalidModeVector
[
{"_key": "key", "invalid_error":  [1, "invalid", 3]}
]
# [[0,1337566253.89858,0.000355720520019531],1]
load --table InvalidModeVector
[
{"_key": "key", "invalid_warn":   [1, "invalid", 3]}
]
# [[0,1337566253.89858,0.000355720520019531],1]
load --table InvalidModeVector
[
{"_key": "key", "invalid_ignore": [1, "invalid", 3]}
]
# [[0,1337566253.89858,0.000355720520019531],1]
select \
  --table InvalidModeVector \
  --output_columns invalid_error,invalid_warn,invalid_ignore
# [
#   [
#     0,
#     1337566253.89858,
#     0.000355720520019531
#   ],
#   [
#     [
#       [
#         1
#       ],
#       [
#         [
#           "invalid_error",
#           "Int32"
#         ],
#         [
#           "invalid_warn",
#           "Int32"
#         ],
#         [
#           "invalid_ignore",
#           "Int32"
#         ]
#       ],
#       [
#         [
#           1,
#           3
#         ],
#         [
#           1,
#           3
#         ],
#         [
#           1,
#           3
#         ]
#       ]
#     ]
#   ]
# ]

7.3.12.4. 引数#

このセクションではすべての引数について説明します。

7.3.12.4.1. 必須引数#

いくつか必須の引数があります。

7.3.12.4.1.1. table#

新しいカラムを追加する対象となる既存のテーブル名を指定します。

7.3.12.4.1.2. name#

作成するカラム名を指定します。

カラム名は同じテーブル内で一意でなければいけません。

利用可能な文字は以下の通りです。

  • 0 .. 9 (数字)

  • a .. z (アルファベット。小文字)

  • A .. Z (アルファベット。大文字)

  • # (シャープ)

  • @ (アットマーク)

  • - (ハイフン)

  • _ (アンダースコア)(注: 最初の文字としてアンダースコアを使うことはできません。)

上記の文字を1つ以上使って名前を決めます。 _name というように、最初の文字に _ を使えないことに注意してください。

7.3.12.4.1.3. flags#

カラムの種類とカラムをカスタマイズするオプションを指定します。

指定可能なフラグは以下の通りです。

フラグ

説明

COLUMN_SCALAR

スカラーカラム。値を1つ保存できます。 スカラーカラム あるいは スカラーカラムを作成 も見てください。

COLUMN_VECTOR

ベクターカラム。複数の値を保存できます。 ベクターカラム あるいは ベクターカラムを作成 も見てください。

COLUMN_INDEX

インデックスカラム。高速に検索するためのデータを保存します。 インデックスカラム あるいは インデックスカラムを作成 も見てください。

COMPRESS_ZLIB

zlibを使ったカラム値圧縮機能を有効にします。zlibサポート付きのGroongaが必要です。

zlibを使った圧縮はLZ4を使った圧縮よりも空間効率がよいです。しかし、zlibを使った圧縮はLZ4を使った圧縮よりも遅いです。

このフラグは COLUMN_SCALARCOLUMN_VECTOR でだけ使えます。

COMPRESS_LZ4

LZ4を使ったカラム値圧縮機能を有効にします。LZ4サポート付きのGroongaが必要です。

LZ4を使った圧縮はzlibを使った圧縮よりも速いです。しかし、LZ4を使った圧縮はzlibを使った圧縮よりも空間効率が低いです。

このフラグは COLUMN_SCALARCOLUMN_VECTOR でだけ使えます。

COMPRESS_ZSTD

Zstandardを使ったカラム値圧縮機能を有効にします。Zstandardサポート付きのGroongaが必要です。

Zstandardを使った圧縮はzlibを使った圧縮よりも速いです。しかも、Zstandardを使った圧縮はzlibを使った圧縮と同程度の空間効率です。

このフラグは COLUMN_SCALARCOLUMN_VECTOR でだけ使えます。

COMPRESS_FILTER_SHUFFLE

バージョン 13.0.8 で追加.

このフラグは圧縮前にデータをフィルタリングすることで COMPRESS_ZLIB / COMPRESS_LZ4 / COMPRESS_ZSTD の圧縮率を高めるためのフラグです。

ただし、データによって効果があることもあれば効果がないこともあります。圧縮率が下がることもありえます。

また、このフラグを有効にすることで追加の処理が入るのでカラムの保存・参照処理は確実に遅くなります。

なお、 COMPRESS_ZLIB / COMPRESS_LZ4 / COMPRESS_ZSTD を指定しない場合は BloscLZ という圧縮アルゴリズムが使われるので、このフラグを有効にすることでほとんどの場合は未圧縮の場合よりもサイズが小さくなります。

しかし、データによってはこのフラグを有効にせずに単に COMPRESS_ZLIB / COMPRESS_LZ4 / COMPRESS_ZSTD を指定するだけで十分であることもあるため、実際のデータにあわせて適切にフラグを設定するようにしてください。

COMPRESS_FILTER_SHUFFLE` フラグはBloscサポートが有効になっていないと無視されることに注意してください。各種パッケージでは有効になっていますが、自分でビルドするときは明示的に有効にする必要があります。自分でビルドする場合は その他 を参照してください。

このフラグは COLUMN_VECTOR でのみ使用できます。 COLUMN_SCALAR のときはこのフラグは無視されます。

では、このフラグがどのようなデータに対して有効かを記載します。

このフラグはNバイト目の要素に着目してデータを並び替えます。

まず、ベクターカラム内の各要素の0バイト目だけのデータを集めて連続で配置します。その後、同様に1バイト目のデータだけを集めて連続で配置するということをすべてのバイトに対して繰り返します。

COMPRESS_ZLIBCOMPRESS_LZ4COMPRESS_ZSTD といった圧縮アルゴリズムは同じ値が連続しているデータだと圧縮率が高くなる傾向があります。

具体的には、以下のように動作します。

例えば、 UInt16 のベクターカラム [1, 1051, 515] があるとします。 これをリトルエンディアンのバイト列で表現すると以下のようになります。

| Byte 0 | Byte 1 |  | Byte 0 | Byte 1 |  | Byte 0 | Byte 1 |
|--------|--------|  |--------|--------|  |--------|--------|
| 0x01   | 0x00   |, | 0x1b   | 0x04   |, | 0x03   | 0x02   |

このフラグは、上記の Byte 0 の値をまとめ、その後 Byte 1 のデータをまとめて、以下のようなデータを作るフラグです。この、Nバイト毎にまとめる操作を以後、シャッフルと呼びます。上記のデータをシャッフルすると以下のようになります。

| Byte 0 | Byte 0 | Byte 0 |  | Byte 1 | Byte 1 | Byte 1 |
|--------|--------|--------|  |--------|--------|--------|
| 0x01   | 0x1b   | 0x03   |, | 0x00   | 0x04   | 0x02   |

ポイントは「同じ値が連続する箇所があるかどうか?」です。 上記の例を見てみると、シャッフル後のデータは同じ値が連続している箇所がありません。このようなデータでは、シャッフルしても圧縮率の向上に寄与しないため、このフラグを適用するには不向きなデータです。

一方で、 UInt16 のベクターカラム [1, 2, 3] というデータでは、シャッフルすると以下のようになります。まず、説明のため UInt16[1, 2, 3] を以下のようなリトルエンディアンのバイト列表現にします。

| Byte 0 | Byte 1 |  | Byte 0 | Byte 1 |  | Byte 0 | Byte 1 |
|--------|--------|  |--------|--------|  |--------|--------|
| 0x01   | 0x00   |, | 0x02   | 0x00   |, | 0x03   | 0x00   |

そして、 UInt16[1, 2, 3] をシャッフルすると以下のようなデータになります。

| Byte 0 | Byte 0 | Byte 0 |  | Byte 1 | Byte 1 | Byte 1 |
|--------|--------|--------|  |--------|--------|--------|
| 0x01   | 0x02   | 0x03   |, | 0x00   | 0x00   | 0x00   |

UInt16[1, 2, 3] というデータだと、シャッフル後に Byte 1 のデータがすべて 0x00 になり、同じ値が連続することになります。したがって、このようなデータは圧縮率の向上に寄与するので、このフラグを適用するのに向いているデータです。

浮動小数点数であれば、符号と指数部が同じデータが該当します。IEEE 754 形式の単精度浮動小数点数の場合、符号は31ビット目に配置され、指数部は30ビット目から23ビット目に配置されます。符号ビットと指数部の上位7ビットで最上位のバイトが構成されるので符号ビットと指数部の上位7ビットが同じになれば、シャッフル後は同じ値が連続することになるからです。

例えば、 Float32[0.5, 0.6] というデータは、IEEE 754 形式の単精度浮動小数点数で表現すると以下のように符号ビットと指数部が同一です。

| 仮数部(23bit)                 | 指数部(8bit) | 符号(1bit) |
|------------------------------|-------------|------------|
| 0000 0000 0000 0000 0000 000 | 0111 1110   |  0         |
| 0101 1001 1001 1001 1001 100 | 0111 1110   |  0         |

これを、シャッフルすると以下のようになり、 Byte 3 に同じ値が連続することになります。

| Byte 0 | Byte 0 |  | Byte 1 | Byte 1 |  | Byte 2 | Byte 2 |  | Byte 3 | Byte 3 |
|--------|--------|  |--------|--------|  |--------|--------|  |--------|--------|
| 0x00   | 0x9a   |, | 0x00   | 0x99   |, | 0x00   | 0x19   |, | 0x3f   | 0x3f   |

Float / Float32 型のデータの場合は、 COMPRESS_FILTER_TRUNCATE_PRECISION_1BYTE または COMPRESS_FILTER_TRUNCATE_PRECISION_2BYTES を組み合わせて使うこともできるので、 COMPRESS_FILTER_TRUNCATE_PRECISION_1BYTECOMPRESS_FILTER_TRUNCATE_PRECISION_2BYTES の説明も合わせて参照してください。

COMPRESS_FILTER_BYTE_DELTA

バージョン 13.0.8 で追加.

このフラグは圧縮前にデータをフィルタリングすることで COMPRESS_ZLIB / COMPRESS_LZ4 / COMPRESS_ZSTD の圧縮率を高めるためのフラグです。

ただし、データによって効果があることもあれば効果がないこともあります。圧縮率が下がることもありえます。

また、このフラグを有効にすることで追加の処理が入るのでカラムの保存・参照処理は確実に遅くなります。

なお、 COMPRESS_ZLIB / COMPRESS_LZ4 / COMPRESS_ZSTD を指定しない場合は BloscLZ という圧縮アルゴリズムが使われるので、このフラグを有効にすることでほとんどの場合は未圧縮の場合よりもサイズが小さくなります。

しかし、データによってはこのフラグを有効にせずに単に COMPRESS_ZLIB / COMPRESS_LZ4 / COMPRESS_ZSTD を指定するだけで十分であることもあるため、実際のデータにあわせて適切にフラグを設定するようにしてください。

COMPRESS_FILTER_SHUFFLE` フラグはBloscサポートが有効になっていないと無視されることに注意してください。各種パッケージでは有効になっていますが、自分でビルドするときは明示的に有効にする必要があります。自分でビルドする場合は その他 を参照してください。

このフラグは COLUMN_VECTOR でのみ使用できます。 COLUMN_SCALAR のときはこのフラグは無視されます。

では、このフラグがどのようなデータに対して有効かを記載します。

このフラグは、圧縮対象の値のバイト間の差分を計算するフラグです。例えば UInt8 のベクターカラム [1, 2, 3, 4, 5] というデータの場合、このフラグを適用すると [1, (2-1), (3-2), (4-3), (5-4)] = [1, 1, 1, 1, 1] というデータになります。

上記のように差分データを計算することで、同じ値が連続するデータを作り圧縮率を向上させることを狙っています。ポイントは、各要素間の差分を計算することで、同じ値が連続するデータを作り出すことにあります。

したがって、差分を計算しても同じ値が連続するデータを作り出すことができないデータは、このフラグを適用するには不向きなデータです。どのようなデータであれば、差分を計算して同じ値が連続するようになるのかを以下に記載します。

まずは、前述の例でもあげた、 UInt8[1, 2, 3, 4, 5] というような一定のペースで値が増加していくデータです。一定のペースなので、 UInt8[1, 11, 21, 31, 41] のように 10 ずつ値が増加するようなデータでも良いです。

次に、 UInt8[5, 5, 5, 5, 5] のように同じ値が連続するデータです。このデータは差分を計算すると [5, 0, 0, 0, 0] となり、 0 が連続するようになります。逆に、 UInt8[1, 255, 2, 200, 1] のように差分を計算しても同じ値が連続しないデータは、このフラグには不向きなデータです。

ただ、差分を計算しても同じ値が連続しなかったり、差分自体が大きい値になる場合でも、 COMPRESS_FILTER_SHUFFLE を合わせて使うことで圧縮率を向上させられるケースもあります。

例えば、 UInt32[4526677, 4592401, 4658217, 4723879] では、単に COMPRESS_FILTER_BYTE_DELTA を適用しただけでは、 [4526677, 65724, 65816, 65662] になります。このデータでは同じ値は連続しませんし、差分自体も大きい値です。

しかし、このデータに COMPRESS_FILTER_SHUFFLE を適用すると以下のようになります。説明のため、まず以下のように UInt32[4526677, 4592401, 4658217, 4723879] をリトルエンディアンのバイト列で表現します。

| Byte 0 | Byte 1 | Byte 2 | Byte 3 |  | Byte 0 | Byte 1 | Byte 2 | Byte 3 |  | Byte 0 | Byte 1 | Byte 2 | Byte 3 |  | Byte 0 | Byte 1 | Byte 2 | Byte 3 |
|--------|--------|--------|--------|  |--------|--------|--------|--------|  |--------|--------|--------|--------|  |--------|--------|--------|--------|
| 0x55   | 0x12   | 0x45   | 0x00   |, | 0x11   | 0x13   | 0x46   | 0x00   |, | 0x29   | 0x14   | 0x47   | 0x00   |, | 0xA7   | 0x14   | 0x48   | 0x00   |

このデータに対して、 COMPRESS_FILTER_SHUFFLE を適用すると以下のようなバイト列になります。

| Byte 0 | Byte 0 | Byte 0 | Byte 0 |  | Byte 1 | Byte 1 | Byte 1 | Byte 1 |  | Byte 2 | Byte 2 | Byte 2 | Byte 2 |  | Byte 3 | Byte 3 | Byte 3 | Byte 3 |
|--------|--------|--------|--------|  |--------|--------|--------|--------|  |--------|--------|--------|--------|  |--------|--------|--------|--------|
| 0x55   | 0x11   | 0x29   | 0xA7   |, | 0x12   | 0x13   | 0x14   | 0x14   |, | 0x45   | 0x46   | 0x47   | 0x48   |, | 0x00   | 0x00   | 0x00   | 0x00   |

シャッフル後の Byte1 のデータと Byte2Byte 3 のデータに注目してください。 Byte 1 のデータの差分は [0x12, 0x01, 0x01, 0x00] , Byte 2 のデータの差分は [0x45, 0x01, 0x01, 0x01] , Byte 3 のデータの差分は [0x00, 0x00, 0x00, 0x00] となり、差分の値が小さく、また同じ値が連続するようになります。

このように、 COMPRESS_FILTER_BYTE_DELTA を適用しただけでは圧縮率の向上が見込めないデータでも、 COMPRESS_FILTER_SHUFFLE と合わせて使うことで圧縮率の向上を見込めるケースがあります。

ただし、 COMPRESS_FILTER_SHUFFLE は同じバイトのデータを集めるフィルターなので、1バイトのデータに対して適用しても意味がありません。(1バイトのデータの場合は、シャッフルしてもしなくても同じデータ列になるためです。)したがって、 COMPRESS_FILTER_BYTE_DELTACOMPRESS_FILTER_SHUFFLE を合わせて使う場合は、 Int8 / UInt8 以外のデータに対して使用してください。

COMPRESS_FILTER_TRUNCATE_PRECISION_1BYTE

バージョン 13.0.8 で追加.

このフラグは圧縮前にデータをフィルタリングすることで COMPRESS_ZLIB / COMPRESS_LZ4 / COMPRESS_ZSTD の圧縮率を高めるためのフラグです。

ただし、データによって効果があることもあれば効果がないこともあります。圧縮率が下がることもありえます。

また、このフラグを有効にすることで追加の処理が入るのでカラムの保存・参照処理は確実に遅くなります。

なお、 COMPRESS_ZLIB / COMPRESS_LZ4 / COMPRESS_ZSTD を指定しない場合は BloscLZ という圧縮アルゴリズムが使われるので、このフラグを有効にすることでほとんどの場合は未圧縮の場合よりもサイズが小さくなります。

しかし、データによってはこのフラグを有効にせずに単に COMPRESS_ZLIB / COMPRESS_LZ4 / COMPRESS_ZSTD を指定するだけで十分であることもあるため、実際のデータにあわせて適切にフラグを設定するようにしてください。

COMPRESS_FILTER_SHUFFLE` フラグはBloscサポートが有効になっていないと無視されることに注意してください。各種パッケージでは有効になっていますが、自分でビルドするときは明示的に有効にする必要があります。自分でビルドする場合は その他 を参照してください。

このフラグは COLUMN_VECTOR でのみ使用できます。 COLUMN_SCALAR のときはこのフラグは無視されます。

このフラグは、 Float / Float32 でのみ使用できます。また、 COMPRESS_FILTER_SHUFFLE と組み合わせて使うことを想定しています。

では、このフラグがどのようなデータに対して有効かを記載します。

このフラグは、 Float / Float32 型のベクターカラムの各要素の精度を1バイト落とします。精度を落とすとは、浮動小数点数の最下位バイトをすべて0にすることです。

例えば、 Float32[1.25, 3.67, 4.55] というデータは、IEEE 754 形式の単精度浮動小数点数で表現すると以下のように表現できます。

| 仮数部(23bit)                 | 指数部(8bit) | 符号(1bit) |
|------------------------------|-------------|------------|
| 0000 0000 0000 0000 0000 010 | 1111 1110   | 0          |
| 0001 0010 1000 0111 0101 011 | 0000 0001   | 0          |
| 0101 1001 1001 1001 1000 100 | 1000 0001   | 0          |

このフラグを適用すると、最下位バイトをすべて0にするので以下のようなデータになります。仮数部の最下位バイトが0になっていることに注目してください。

| 仮数部(23bit)                 | 指数部(8bit) | 符号(1bit) |
|------------------------------|-------------|------------|
| 0000 0000 0000 0000 0000 010 | 1111 1110   | 0          |
| 0000 0000 1000 0111 0101 011 | 0000 0001   | 0          |
| 0000 0000 1001 1001 1000 100 | 1000 0001   | 0          |

ここまでが、このフラグ単独で使用した時に実行される操作です。前述の通り、このフラグは COLUMN_FILTER_SHUFFLE と組み合わせて使うことを想定しています。そのため、ここから更にデータをシャッフルすることで、圧縮率の向上を期待しています。

COMPRESS_FILTER_TRUNCATE_PRECISION_1BYTE を適用したデータをシャッフルすると以下のようなデータになります。

| Byte 0 | Byte 0 | Byte 0 |  | Byte 1 | Byte 1 | Byte 1 |  | Byte 2 | Byte 2 | Byte 2 |  | Byte 3 | Byte 3 | Byte 3 |
|--------|--------|--------|  |--------|--------|--------|  |--------|--------|--------|  |--------|--------|--------|
| 0x00   | 0x00   | 0x00   |, | 0x00   | 0xe1   | 0x99   |, | 0xa0   | 0x6a   | 0x91   |, | 0x3f   | 0x40   | 0x40   |

Byte 0 に注目してください。 Byte 00 が連続するデータになります。COMPRESS_FILTER_TRUNCATE_PRECISION_1BYTE を適用せずにシャッフルすると以下のようなデータになり、どのバイトも同じ値は連続していません。

| Byte 0 | Byte 0 | Byte 0 |  | Byte 1 | Byte 1 | Byte 1 |  | Byte 2 | Byte 2 | Byte 2 |  | Byte 3 | Byte 3 | Byte 3 |
|--------|--------|--------|  |--------|--------|--------|  |--------|--------|--------|  |--------|--------|--------|
| 0x00   | 0x48   | 0x9a   |, | 0x00   | 0xe1   | 0x99   |, | 0xa0   | 0x6a   | 0x91   |, | 0x3f   | 0x40   | 0x40   |

このように単純にシャッフルしただけでは、圧縮率の向上が見込めないデータでも COMPRESS_FILTER_TRUNCATE_PRECISION_1BYTE を適用することで、圧縮率の向上が見込める場合があります。ただし、圧縮対象の浮動小数点数の精度が1バイト分落ちるので、その分不正確なデータになることに注意してください。

COMPRESS_FILTER_TRUNCATE_PRECISION_2BYTES

バージョン 13.0.8 で追加.

このフラグは圧縮前にデータをフィルタリングすることで COMPRESS_ZLIB / COMPRESS_LZ4 / COMPRESS_ZSTD の圧縮率を高めるためのフラグです。

ただし、データによって効果があることもあれば効果がないこともあります。圧縮率が下がることもありえます。

また、このフラグを有効にすることで追加の処理が入るのでカラムの保存・参照処理は確実に遅くなります。

なお、 COMPRESS_ZLIB / COMPRESS_LZ4 / COMPRESS_ZSTD を指定しない場合は BloscLZ という圧縮アルゴリズムが使われるので、このフラグを有効にすることでほとんどの場合は未圧縮の場合よりもサイズが小さくなります。

しかし、データによってはこのフラグを有効にせずに単に COMPRESS_ZLIB / COMPRESS_LZ4 / COMPRESS_ZSTD を指定するだけで十分であることもあるため、実際のデータにあわせて適切にフラグを設定するようにしてください。

COMPRESS_FILTER_SHUFFLE` フラグはBloscサポートが有効になっていないと無視されることに注意してください。各種パッケージでは有効になっていますが、自分でビルドするときは明示的に有効にする必要があります。自分でビルドする場合は その他 を参照してください。

このフラグは COLUMN_VECTOR でのみ使用できます。 COLUMN_SCALAR のときはこのフラグは無視されます。

このフラグは、 Float / Float32 でのみ使用できます。また、 COMPRESS_FILTER_SHUFFLE と組み合わせて使うことを想定しています。

では、このフラグがどのようなデータに対して有効かを記載します。

このフラグは、 Float / Float32 型のベクターカラムの各要素の精度を2バイト落とします。精度を落とすとは、浮動小数点数の下位2バイトをすべて 0 にすることです。

例えば、 Float32[1.25, 3.67, 4.55] というデータは、IEEE 754 形式の単精度浮動小数点数で表現すると以下のように表現できます。

| 仮数部(23bit)                 | 指数部(8bit) | 符号(1bit) |
|------------------------------|-------------|------------|
| 0000 0000 0000 0000 0000 010 | 1111 1110   | 0          |
| 0001 0010 1000 0111 0101 011 | 0000 0001   | 0          |
| 0101 1001 1001 1001 1000 100 | 1000 0001   | 0          |

このフラグを適用すると、下位2バイトをすべて 0 にするので以下のようなデータになります。仮数部の下位2バイトがすべて 0 になっていることに注目してください。

| 仮数部(23bit)                 | 指数部(8bit) | 符号(1bit) |
|------------------------------|-------------|------------|
| 0000 0000 0000 0000 0000 010 | 1111 1110   | 0          |
| 0000 0000 0000 0000 0101 011 | 0000 0001   | 0          |
| 0000 0000 0000 0000 1000 100 | 1000 0001   | 0          |

ここまでが、このフラグ単独で使用した時に実行される操作です。前述の通り、このフラグは COLUMN_FILTER_SHUFFLE と組み合わせて使うことを想定しています。そのため、ここから更にデータをシャッフルすることで、圧縮率の向上を期待しています。

COMPRESS_FILTER_TRUNCATE_PRECISION_2BYTE を適用したデータをシャッフルすると以下のようなデータになります。

| Byte 0 | Byte 0 | Byte 0 |  | Byte 1 | Byte 1 | Byte 1 |  | Byte 2 | Byte 2 | Byte 2 |  | Byte 3 | Byte 3 | Byte 3 |
|--------|--------|--------|  |--------|--------|--------|  |--------|--------|--------|  |--------|--------|--------|
| 0x00   | 0x00   | 0x00   |, | 0x00   | 0x00   | 0x00   |, | 0xa0   | 0x6a   | 0x91   |, | 0x3f   | 0x40   | 0x40   |

Byte 0Byte 1 に注目してください。 Byte 0Byte 10 が連続するデータになります。

COMPRESS_FILTER_TRUNCATE_PRECISION_2BYTE を適用せずにシャッフルすると以下のようなデータになり、どのバイトも同じ値は連続していません。

| Byte 0 | Byte 0 | Byte 0 |  | Byte 1 | Byte 1 | Byte 1 |  | Byte 2 | Byte 2 | Byte 2 |  | Byte 3 | Byte 3 | Byte 3 |
|--------|--------|--------|  |--------|--------|--------|  |--------|--------|--------|  |--------|--------|--------|
| 0x00   | 0x48   | 0x9a   |, | 0x00   | 0xe1   | 0x99   |, | 0xa0   | 0x6a   | 0x91   |, | 0x3f   | 0x40   | 0x40   |

このように単純にシャッフルしただけでは、圧縮率の向上が見込めないデータでも COMPRESS_FILTER_TRUNCATE_PRECISION_2BYTE を適用することで、圧縮率の向上が見込める場合があります。

ただし、圧縮対象の浮動小数点数の精度が2バイト分落ちるので、その分不正確なデータになることに注意してください。

WITH_SECTION

インデックスカラムのセクションサポートを有効にします。

セクションサポートが有効になると、同じインデックスカラムで複数の文書をサポートできます。

マルチカラムインデックスカラムを作成するときはこのフラグを指定しなければいけません。詳細は マルチカラムインデックスカラムを作成 を見てください。

セクションサポートを有効にするとインデックスカラムが使う領域が増えます。セクションサポートが必要ない場合は有効にしないでください。

このフラグは COLUMN_INDEX でだけ有効です。

WITH_WEIGHT

ベクターカラム・インデックスカラムの重みサポートを有効にします。

ベクターカラムの重みサポートを有効にすると各要素に重みを追加できます。インデックスカラムの重みサポートを有効にすると各ポスティングに重みを追加できます。これらは検索スコアの調整に役立ちます。

adjuster を使う場合はこのフラグを指定します。詳細は 重み付きベクターカラムの作成 を見てください。

重みをサポートすると使用する領域が増えます。重みが必要ない場合は有効にしないでください。

COLUMN_VECTORCOLUMN_INDEX でだけこのフラグは有効です。

WEIGHT_FLOAT32

バージョン 10.0.3 で追加.

重みの値に32bit非負整数ではなく32bit浮動小数点を使います。

WITH_WEIGHT も指定する必要があります。

COLUMN_VECTORCOLUMN_INDEX でだけこのフラグは有効です。

WITH_POSITION

インデックスカラムの位置情報サポートを有効にします。これはインデックスカラムを完全転置インデックスにするということです。(インデックスカラムは転置インデックスとして実装されています。)

位置情報サポートが有効だと各ポスティングにドキュメントでの出現位置を追加できます。この情報はフレーズ検索をするときに必要になります。全文検索用のインデックスは位置情報サポートを有効にしなければいけません。なぜなら、全文検索はフレーズ検索を使うからです。

全文検索インデックスカラムを作成するときはこのフラグを指定してください。詳細は 全文検索用のインデックスカラムを作成 を見てください。

位置情報をサポートすると使用する領域が増えます。位置情報サポートが必要ない場合は有効にしないでください。

このフラグは COLUMN_INDEX でだけ有効です。

INDEX_SMALL

バージョン 6.0.8 で追加.

小さなインデックスを作成するときに指定します。

インデックス対象のデータが小さいときは小さなインデックスカラムで十分です。小さなインデックスカラムは通常のインデックスカラム・中サイズのインデックスカラムよりも使用メモリーが少ないです。「小さいデータ」とはなにか、このフラグをどうやって使えばよいかは 小さなインデックスカラムを作成 を見てください。

このフラグは COLUMN_INDEX でだけ有効です。

INDEX_MEDIUM

バージョン 6.0.8 で追加.

中サイズのインデックスカラムを作成するときに指定します。

インデックス対象のデータが中サイズなら中サイズのインデックスカラムで十分です。中サイズのインデックスカラムは通常のインデックスカラムよりも使用メモリー量が少ないです。「中サイズのデータ」とはなにか、このフラグをどうやって使えばよいかは 中サイズのインデックスカラムを作成 を見てください。

このフラグは COLUMN_INDEX でだけ有効です。

INDEX_LARGE

バージョン 9.0.2 で追加.

大きなインデックスを作成するときに指定します。

インデックス対象のデータが大きいときは大きなインデックスカラムを使う必要があります。大きなインデックスカラムは通常のインデックスカラムよりもメモリーを使いますが、通常のインデックスカラムよりも多くのデータを扱えます。「大きなデータ」とはなにか、このフラグをどうやって使えばよいかは 大きなインデックスカラムを作成 を見てください。

このフラグは COLUMN_INDEX でだけ有効です。

MISSING_ADD

バージョン 12.0.2 で追加.

複数の MISSING_* フラグを指定することはできません。これらは排他です。

これは参照スカラーカラムと参照ベクターカラムでのみ意味があります。

このフラグが指定されたカラムに、参照されているテーブルに存在しないキーを指定したら、参照されているテーブルに新しいレコードを自動的に作ります。

MISSING_* フラグを指定していない場合、デフォルトで MISSING_ADD が使われます。

ミッシングモード も参照してください。

このフラグは COLUMN_SCALARCOLUMN_VECTOR でだけ使えます。

MISSING_IGNORE

バージョン 12.0.2 で追加.

複数の MISSING_* フラグを指定することはできません。これらは排他です。

これは参照スカラーカラムと参照ベクターカラムでのみ意味があります。

このフラグが指定されたカラムに、参照されているテーブルに存在しないキーを指定したら、その値は無視されます。もし、そのカラムがスカラーカラムなら GRN_ID_NIL0 )が格納されます。なぜならGroongaはNULL値をサポートしていないからです。もし、そのカラムがベクターカラムなら値からその要素は削除されます。たとえば、 ["existent1", "nonexistent", "existent2"] がそのベクターカラムにセットされ、 "nonexistent" レコードが参照されているテーブルに存在しない場合、そのベクターカラムには ["existent1", "existent2"] が設定されます。

ミッシングモード も参照してください。

このフラグは COLUMN_SCALARCOLUMN_VECTOR でだけ使えます。

MISSING_NIL

バージョン 12.0.2 で追加.

複数の MISSING_* フラグを指定することはできません。これらは排他です。

これは参照スカラーカラムと参照ベクターカラムでのみ意味があります。

このフラグが指定されたカラムに、参照されているテーブルに存在しないキーを指定したら、その値は GRN_ID_NIL0 )に置き換えられます。

ミッシングモード も参照してください。

このフラグは COLUMN_SCALARCOLUMN_VECTOR でだけ使えます。

INVALID_ERROR

バージョン 12.0.2 で追加.

複数の INVALID_* フラグを指定することはできません。これらは排他です。

このフラグを指定しているときに不正な値が指定されたら、 プロセスログ にエラーログが記録されます。

たとえば、 Int32 カラムの場合は "STRING" は不正な値です。

カラムがスカラーカラムの場合は、 load もエラーを返します。

カラムがベクターカラムの場合、 load はエラーを返しませんが、ベクター内の不正な値は削除されるか GRN_ID_NIL0 )に置き換えられます。どっちになるかはこのカラムに指定された MISSING_* フラグに依ります。

注釈

12.0.2での非互換の変更です。12.0.2より前は load もエラーを返していました。

INVALID_* フラグを指定しない場合はデフォルト値として INVALID_ERROR が使われます。

不正モード も参照してください。

このフラグは COLUMN_SCALARCOLUMN_VECTOR でだけ使えます。

INVALID_WARN

バージョン 12.0.2 で追加.

複数の INVALID_* フラグを指定することはできません。これらは排他です。

このフラグが指定されたカラムに不正な値が指定された場合は プロセスログ に警告が記録されますがエラーは返りません。

たとえば、 Int32 カラムの場合は "STRING" は不正な値です。

このカラムがベクターカラムの場合は、不正な値が削除されるか GRN_ID_NIL0 )に置換されるかはこのカラムの MISSING_* フラグに依ります。

不正モード も参照してください。

このフラグは COLUMN_SCALARCOLUMN_VECTOR でだけ使えます。

INVALID_IGNORE

バージョン 12.0.2 で追加.

複数の INVALID_* フラグを指定することはできません。これらは排他です。

このフラグが指定されたカラムに不正な値が指定された場合、単に無視されます。

たとえば、 Int32 カラムの場合は "STRING" は不正な値です。

このカラムがベクターカラムの場合は、不正な値が削除されるか GRN_ID_NIL0 )に置換されるかはこのカラムの MISSING_* フラグに依ります。

不正モード も参照してください。

このフラグは COLUMN_SCALARCOLUMN_VECTOR でだけ使えます。

COLUMN_${TYPE} フラグのどれかを必ず指定します。2つ以上の COLUMN_${TYPE} フラグを指定してはいけません。たとえば、 COLUMN_SCALAR|COLUMN_VECTOR は不正な指定です。

WITH_SECTION|WITH_POSITION というように、 | (縦棒)で複数のフラグを組み合わせることができます。

7.3.12.4.1.4. type#

カラムの値の型を指定します。

カラムがスカラーカラムかベクターカラムなら利用可能な型は次の通りです。

  • データ型 で説明している組み込みの型

  • ユーザーが定義したテーブル

カラムがインデックスカラムのときの利用可能な型は次の通りです。

  • ユーザーが定義したテーブル

以下も見てください。

7.3.12.4.2. 省略可能引数#

省略可能な引数があります。

7.3.12.4.2.1. source#

インデックス対象のカラムを指定します。 source パラメーターには1つ以上のカラムを指定できます。

このパラメーターはインデックスカラムでだけ利用可能です。

type で指定したテーブルのカラムだけ指定できます。テーブルのキーをインデックス対象にしたい場合は _key 疑似カラムを指定します。

source パラメーターに複数のカラムを指定するときは _key,roles というように , (コンマ)で区切ります。

7.3.12.4.2.2. path#

バージョン 10.0.7 で追加.

カラムを格納するパスを指定します。

このオプションは、高速なストレージ(SSDなど)によく使うカラムを格納し、低速なストレージ(HDDなど)にあまり使わないカラムを格納したいときに有用です。

このオプションでは、絶対パスまたは相対パスを使えます。相対パスを指定した場合は、 groonga プロセスのカレントディレクトリーからパスを解決します。

デフォルト値はありません。

7.3.12.5. 戻り値#

column_create が成功したときは以下のようにボディは true になります:

[HEADER, true]

column_create が失敗したときはボディは false になります:

[HEADER, false]

HEADER にエラーの詳細が含まれます。

HEADER については 出力形式 を参照してください。

7.3.12.6. 参考#