読者です 読者をやめる 読者になる 読者になる

CreateField Blog

オープンソースを使って個人でWebサービスを開発・運営していたブログ

Groonga 6.0.2から多段ドリルダウンが利用可能に

GroongaはC/C++で書かれた国産の全文検索エンジンライブラリです。 サーバとしても組み込みのライブラリとしても利用することが可能です。

Groongaでは従来よりドリルダウン機能(ファセット)が提供されていましたが、 ドリルダウン機能の結果をつかってさらにドリルダウンするといったことはできませんでした。

Groonga6.0.2よりドリルダウン結果を使った多段のドリルダウンが利用できるようになりました。

これにより、たとえば、以下のようなユースケースで役に立つと思います。

  • タグのメタデータでのグループ
  • 大分類、中分類、小分類での段階的グループ

タグのメタデータのグループ結果

Groongaでは、以下のようにタグやカテゴリデータを別テーブルにして持つことができます。 この別テーブルにメタデータを追加で持たせることにより、さらに、そのメタデータで集計することができます。

たとえば、本の著者データに、著者の性別や、年齢、住所などを持たせて、それごとに集計することができます。

table_create Authors TABLE_PAT_KEY ShortText
[[0,0.0,0.0],true]
column_create Authors sex COLUMN_SCALAR ShortText
[[0,0.0,0.0],true]
table_create Books TABLE_HASH_KEY ShortText
[[0,0.0,0.0],true]
column_create Books authors COLUMN_VECTOR Authors
[[0,0.0,0.0],true]
load --table Books
[
{"_key": "Hello Groonga", "authors": ["Taro", "Hanako"]},
{"_key": "The first step for Groonga", "authors": ["Taro"]},
{"_key": "Mastering Groonga", "authors": ["Taro", "Hanako"]}
]
[[0,0.0,0.0],3]
load --table Authors
[
{"_key": "Taro", "sex": "Male"},
{"_key": "Hanako", "sex": "Female"}
]
[[0,0.0,0.0],2]
select Books \
  --drilldown[authors].keys authors \
  --drilldown[authors].output_columns _key,_nsubrecs \
  --drilldown[sex].table authors \
  --drilldown[sex].keys sex \
  --drilldown[sex].output_columns _key,_nsubrecs
[
  [
    0,
    0.0,
    0.0
  ],
  [
    [
      [
        3
      ],
      [
        [
          "_id",
          "UInt32"
        ],
        [
          "_key",
          "ShortText"
        ],
        [
          "authors",
          "Authors"
        ]
      ],
      [
        1,
        "Hello Groonga",
        [
          "Taro",
          "Hanako"
        ]
      ],
      [
        2,
        "The first step for Groonga",
        [
          "Taro"
        ]
      ],
      [
        3,
        "Mastering Groonga",
        [
          "Taro",
          "Hanako"
        ]
      ]
    ],
    {
      "authors": [
        [
          2
        ],
        [
          [
            "_key",
            "ShortText"
          ],
          [
            "_nsubrecs",
            "Int32"
          ]
        ],
        [
          "Taro",
          3
        ],
        [
          "Hanako",
          2
        ]
      ],
      "sex": [
        [
          2
        ],
        [
          [
            "_key",
            "ShortText"
          ],
          [
            "_nsubrecs",
            "Int32"
          ]
        ],
        [
          "Male",
          1
        ],
        [
          "Female",
          1
        ]
      ]
    }
  ]
]

メタデータを他のテーブルにして一元管理できて便利ですね。

大分類、中分類、小分類でのグループ

たとえば、日本->東京->新宿区など、階層的な分類を行うことができます。

table_create Addresses TABLE_PAT_KEY ShortText
[[0,0.0,0.0],true]
column_create Addresses country COLUMN_SCALAR ShortText
[[0,0.0,0.0],true]
table_create Authors TABLE_PAT_KEY ShortText
[[0,0.0,0.0],true]
column_create Authors address COLUMN_SCALAR Addresses
[[0,0.0,0.0],true]
table_create Books TABLE_HASH_KEY ShortText
[[0,0.0,0.0],true]
column_create Books authors COLUMN_VECTOR Authors
[[0,0.0,0.0],true]
load --table Books
[
{"_key": "Hello Groonga", "authors": ["Taro", "Hanako"]},
{"_key": "The first step for Groonga", "authors": ["Taro"]},
{"_key": "Mastering Groonga", "authors": ["Taro", "Hanako"]}
]
[[0,0.0,0.0],3]
load --table Authors
[
{"_key": "Taro", "address": "日本東京都"},
{"_key": "Hanako", "address": "アメリカニューヨーク州"}
]
[[0,0.0,0.0],2]
load --table Addresses
[
{"_key": "日本東京都", "country": "日本"},
{"_key": "アメリカニューヨーク州", "country": "アメリカ"}
]
[[0,0.0,0.0],2]
select Books \
  --drilldown[authors].keys authors \
  --drilldown[authors].output_columns _key,_nsubrecs \
  --drilldown[address].table authors \
  --drilldown[address].keys address \
  --drilldown[address].output_columns _key,_nsubrecs \
  --drilldown[country].table address \
  --drilldown[country].keys country \
  --drilldown[country].output_columns _key,_nsubrecs
[
  [
    0,
    0.0,
    0.0
  ],
  [
    [
      [
        3
      ],
      [
        [
          "_id",
          "UInt32"
        ],
        [
          "_key",
          "ShortText"
        ],
        [
          "authors",
          "Authors"
        ]
      ],
      [
        1,
        "Hello Groonga",
        [
          "Taro",
          "Hanako"
        ]
      ],
      [
        2,
        "The first step for Groonga",
        [
          "Taro"
        ]
      ],
      [
        3,
        "Mastering Groonga",
        [
          "Taro",
          "Hanako"
        ]
      ]
    ],
    {
      "authors": [
        [
          2
        ],
        [
          [
            "_key",
            "ShortText"
          ],
          [
            "_nsubrecs",
            "Int32"
          ]
        ],
        [
          "Taro",
          3
        ],
        [
          "Hanako",
          2
        ]
      ],
      "address": [
        [
          2
        ],
        [
          [
            "_key",
            "ShortText"
          ],
          [
            "_nsubrecs",
            "Int32"
          ]
        ],
        [
          "日本東京都",
          1
        ],
        [
          "アメリカニューヨーク州",
          1
        ]
      ],
      "country": [
        [
          2
        ],
        [
          [
            "_key",
            "ShortText"
          ],
          [
            "_nsubrecs",
            "Int32"
          ]
        ],
        [
          "日本",
          1
        ],
        [
          "アメリカ",
          1
        ]
      ]
    }
  ]
]

全てのレコードでグループ

これはオマケですが、今までレコード単一でしか、グループできませんでしたが、全てのレコードでグループすることができるようになりました。

私は円グラフを書くためにベクターカラムのグループ結果のレコード数の総数が欲しくてこの機能をつくりました。

table_create Authors TABLE_PAT_KEY ShortText
[[0,0.0,0.0],true]
column_create Authors sex COLUMN_SCALAR ShortText
[[0,0.0,0.0],true]
table_create Books TABLE_HASH_KEY ShortText
[[0,0.0,0.0],true]
column_create Books authors COLUMN_VECTOR Authors
[[0,0.0,0.0],true]
load --table Books
[
{"_key": "Hello Groonga", "authors": ["Taro", "Hanako"]},
{"_key": "The first step for Groonga", "authors": ["Taro"]},
{"_key": "Mastering Groonga", "authors": ["Taro", "Hanako"]}
]
[[0,0.0,0.0],3]
load --table Authors
[
{"_key": "Taro", "sex": "Male"},
{"_key": "Hanako", "sex": "Female"}
]
[[0,0.0,0.0],2]
select Books \
  --drilldown[authors].keys authors \
  --drilldown[authors].output_columns _key,_nsubrecs \
  --drilldown[authors_sum].table authors \
  --drilldown[authors_sum].output_columns _key,_sum \
  --drilldown[authors_sum].calc_target _nsubrecs \
  --drilldown[authors_sum].calc_types SUM
[
  [
    0,
    0.0,
    0.0
  ],
  [
    [
      [
        3
      ],
      [
        [
          "_id",
          "UInt32"
        ],
        [
          "_key",
          "ShortText"
        ],
        [
          "authors",
          "Authors"
        ]
      ],
      [
        1,
        "Hello Groonga",
        [
          "Taro",
          "Hanako"
        ]
      ],
      [
        2,
        "The first step for Groonga",
        [
          "Taro"
        ]
      ],
      [
        3,
        "Mastering Groonga",
        [
          "Taro",
          "Hanako"
        ]
      ]
    ],
    {
      "authors": [
        [
          2
        ],
        [
          [
            "_key",
            "ShortText"
          ],
          [
            "_nsubrecs",
            "Int32"
          ]
        ],
        [
          "Taro",
          3
        ],
        [
          "Hanako",
          2
        ]
      ],
      "authors_sum": [
        [
          1
        ],
        [
          [
            "_key",
            "ShortText"
          ],
          [
            "_sum",
            "Int64"
          ]
        ],
        [
          "_all",
          5
        ]
      ]
    }
  ]
]

おわりに

多段のドリルダウンについて紹介しました。

今後は、フィルター結果でのドリルダウンや、レンジなどで集計できたりすると、さらに集計の幅が広がりそうでよさそうですね。