# groonga - オープンソースのカラムストア機能付き全文検索エンジン

- English page

# 4.5. ドリルダウン

You learned how to filter search results and sort ones in the previous sections. Now that you can search as you likes, but how do you summarize the number of records which has specific value in the column?

As you know, there is a naive solution to execute query by every the value of column, then you can get the number of records as a result. It is a simple way, but it is not reasonable to many records.

If you are familiar with SQL, you will doubt with "Is there a similar SQL functionality to `GROUP BY` in Groonga?".

Of course, Groonga provides such a functionality. It's called as `drilldown`.

`drilldown` enables you to get the number of records which belongs to specific the value of column at once.

To illustrate this feature, imagine the case that classification by domain and grouping by country that domain belongs to.

この機能を使った具体的な例を示します。

この例では、 `Site` テーブルに2つのカラムを追加しています。 `domain` カラムはTLD(トップレベルドメイン)に使います。 `country` カラムは国名に使います。これらのカラムの型はドメイン名を主キーとする `SiteDomain` テーブルと国名を主キーとする `SiteCountry` テーブルです。

実行例:

    table_create --name SiteDomain --flags TABLE_HASH_KEY --key_type ShortText
    # [[0, 1337566253.89858, 0.000355720520019531], true]
    table_create --name SiteCountry --flags TABLE_HASH_KEY --key_type ShortText
    # [[0, 1337566253.89858, 0.000355720520019531], true]
    column_create --table Site --name domain --flags COLUMN_SCALAR --type SiteDomain
    # [[0, 1337566253.89858, 0.000355720520019531], true]
    column_create --table Site --name country --flags COLUMN_SCALAR --type SiteCountry
    # [[0, 1337566253.89858, 0.000355720520019531], true]
    load --table Site
    [
    {"_key":"http://example.org/","domain":".org","country":"japan"},
    {"_key":"http://example.net/","domain":".net","country":"brazil"},
    {"_key":"http://example.com/","domain":".com","country":"japan"},
    {"_key":"http://example.net/afr","domain":".net","country":"usa"},
    {"_key":"http://example.org/aba","domain":".org","country":"korea"},
    {"_key":"http://example.com/rab","domain":".com","country":"china"},
    {"_key":"http://example.net/atv","domain":".net","country":"china"},
    {"_key":"http://example.org/gat","domain":".org","country":"usa"},
    {"_key":"http://example.com/vdw","domain":".com","country":"japan"}
    ]
    # [[0, 1337566253.89858, 0.000355720520019531], 9]

`domain` カラムでドリルダウンする例を示します。 3つの値が `domain` カラムでは使われています。".org"、".net"そして".com"です。

実行例:

    select --table Site --limit 0 --drilldown domain
    # [
    #   [
    #     0,
    #     1337566253.89858,
    #     0.000355720520019531
    #   ],
    #   [
    #     [
    #       [
    #         9
    #       ],
    #       [
    #         [
    #           "_id",
    #           "UInt32"
    #         ],
    #         [
    #           "_key",
    #           "ShortText"
    #         ],
    #         [
    #           "country",
    #           "SiteCountry"
    #         ],
    #         [
    #           "domain",
    #           "SiteDomain"
    #         ],
    #         [
    #           "link",
    #           "Site"
    #         ],
    #         [
    #           "links",
    #           "Site"
    #         ],
    #         [
    #           "location",
    #           "WGS84GeoPoint"
    #         ],
    #         [
    #           "title",
    #           "ShortText"
    #         ]
    #       ]
    #     ],
    #     [
    #       [
    #         3
    #       ],
    #       [
    #         [
    #           "_key",
    #           "ShortText"
    #         ],
    #         [
    #           "_nsubrecs",
    #           "Int32"
    #         ]
    #       ],
    #       [
    #         ".org",
    #         3
    #       ],
    #       [
    #         ".net",
    #         3
    #       ],
    #       [
    #         ".com",
    #         3
    #       ]
    #     ]
    #   ]
    # ]

上記のクエリの集計結果です。

`domain` カラムによるドリルダウン
グループ化するカラムの値 | グループ化されたレコード数 | グループ化されたレコードは次のとおり
--- | --- | ---
.org | 3 | http://example.org/ http://example.org/aba http://example.org/gat
.net | 3 | http://example.net/ http://example.net/afr http://example.net/atv
.com | 3 | http://example.com/ http://example.com/rab http://example.com/vdw

ドリルダウン結果は `_nsubrecs` カラムの値として返ります。この場合は、`Site` テーブルは ".org"、".net"、".com"ドメインでグループ化されています。 `_nsubrecs` はグループ化されたドメインが3つのレコードをそれぞれもつことを意味します。

テーブル型を持つカラムに対してドリルダウンを行った場合、参照先のテーブルに存在するカラム値を取得することもできます。ドリルダウンを行ったテーブルには、 `_nsubrecs` という仮想的なカラムが追加されます。このカラムには、グループ化されたレコード数が入ります。

では、参照されているテーブルの詳細を調べてみましょう。 `Site` テーブルは `SiteDomain` テーブルを `domain` カラムの型として使っています。 `--drilldown_output_columns` を参照されているカラムの詳細を知るのに使えます。

実行例:

    select --table Site --limit 0 --drilldown domain --drilldown_output_columns _id,_key,_nsubrecs
    # [
    #   [
    #     0,
    #     1337566253.89858,
    #     0.000355720520019531
    #   ],
    #   [
    #     [
    #       [
    #         9
    #       ],
    #       [
    #         [
    #           "_id",
    #           "UInt32"
    #         ],
    #         [
    #           "_key",
    #           "ShortText"
    #         ],
    #         [
    #           "country",
    #           "SiteCountry"
    #         ],
    #         [
    #           "domain",
    #           "SiteDomain"
    #         ],
    #         [
    #           "link",
    #           "Site"
    #         ],
    #         [
    #           "links",
    #           "Site"
    #         ],
    #         [
    #           "location",
    #           "WGS84GeoPoint"
    #         ],
    #         [
    #           "title",
    #           "ShortText"
    #         ]
    #       ]
    #     ],
    #     [
    #       [
    #         3
    #       ],
    #       [
    #         [
    #           "_id",
    #           "UInt32"
    #         ],
    #         [
    #           "_key",
    #           "ShortText"
    #         ],
    #         [
    #           "_nsubrecs",
    #           "Int32"
    #         ]
    #       ],
    #       [
    #         1,
    #         ".org",
    #         3
    #       ],
    #       [
    #         2,
    #         ".net",
    #         3
    #       ],
    #       [
    #         3,
    #         ".com",
    #         3
    #       ]
    #     ]
    #   ]
    # ]

これでグループ化されたドメインの詳細がわかります。 `domain` の値が".org"であるレコードに対して `country` カラムを使ってドリルダウンしてみましょう。

実行例:

    select --table Site --limit 0 --filter "domain._id == 1" --drilldown country
    # [
    #   [
    #     0,
    #     1337566253.89858,
    #     0.000355720520019531
    #   ],
    #   [
    #     [
    #       [
    #         3
    #       ],
    #       [
    #         [
    #           "_id",
    #           "UInt32"
    #         ],
    #         [
    #           "_key",
    #           "ShortText"
    #         ],
    #         [
    #           "country",
    #           "SiteCountry"
    #         ],
    #         [
    #           "domain",
    #           "SiteDomain"
    #         ],
    #         [
    #           "link",
    #           "Site"
    #         ],
    #         [
    #           "links",
    #           "Site"
    #         ],
    #         [
    #           "location",
    #           "WGS84GeoPoint"
    #         ],
    #         [
    #           "title",
    #           "ShortText"
    #         ]
    #       ]
    #     ],
    #     [
    #       [
    #         3
    #       ],
    #       [
    #         [
    #           "_key",
    #           "ShortText"
    #         ],
    #         [
    #           "_nsubrecs",
    #           "Int32"
    #         ]
    #       ],
    #       [
    #         "japan",
    #         1
    #       ],
    #       [
    #         "korea",
    #         1
    #       ],
    #       [
    #         "usa",
    #         1
    #       ]
    #     ]
    #   ]
    # ]

## 4.5.1. 複数のカラムでドリルダウン

ドリルダウンでは複数のカラムをサポートしています。 `drilldown` パラメータの引数にカンマ区切りの値を指定します。すると一度にまとめてドリルダウン結果を取得できます。

実行例:

    select --table Site --limit 0 --drilldown domain,country
    # [
    #   [
    #     0,
    #     1337566253.89858,
    #     0.000355720520019531
    #   ],
    #   [
    #     [
    #       [
    #         9
    #       ],
    #       [
    #         [
    #           "_id",
    #           "UInt32"
    #         ],
    #         [
    #           "_key",
    #           "ShortText"
    #         ],
    #         [
    #           "country",
    #           "SiteCountry"
    #         ],
    #         [
    #           "domain",
    #           "SiteDomain"
    #         ],
    #         [
    #           "link",
    #           "Site"
    #         ],
    #         [
    #           "links",
    #           "Site"
    #         ],
    #         [
    #           "location",
    #           "WGS84GeoPoint"
    #         ],
    #         [
    #           "title",
    #           "ShortText"
    #         ]
    #       ]
    #     ],
    #     [
    #       [
    #         3
    #       ],
    #       [
    #         [
    #           "_key",
    #           "ShortText"
    #         ],
    #         [
    #           "_nsubrecs",
    #           "Int32"
    #         ]
    #       ],
    #       [
    #         ".org",
    #         3
    #       ],
    #       [
    #         ".net",
    #         3
    #       ],
    #       [
    #         ".com",
    #         3
    #       ]
    #     ],
    #     [
    #       [
    #         5
    #       ],
    #       [
    #         [
    #           "_key",
    #           "ShortText"
    #         ],
    #         [
    #           "_nsubrecs",
    #           "Int32"
    #         ]
    #       ],
    #       [
    #         "japan",
    #         3
    #       ],
    #       [
    #         "brazil",
    #         1
    #       ],
    #       [
    #         "usa",
    #         2
    #       ],
    #       [
    #         "korea",
    #         1
    #       ],
    #       [
    #         "china",
    #         2
    #       ]
    #     ]
    #   ]
    # ]

## 4.5.2. ドリルダウン結果をソートする

ドリルダウン結果をソートしたい場合には `--drilldown_sortby` を使います。指定した `_nsubrecs` カラムを昇順でソートします。

実行例:

    select --table Site --limit 0 --drilldown country --drilldown_sortby _nsubrecs
    # [
    #   [
    #     0,
    #     1337566253.89858,
    #     0.000355720520019531
    #   ],
    #   [
    #     [
    #       [
    #         9
    #       ],
    #       [
    #         [
    #           "_id",
    #           "UInt32"
    #         ],
    #         [
    #           "_key",
    #           "ShortText"
    #         ],
    #         [
    #           "country",
    #           "SiteCountry"
    #         ],
    #         [
    #           "domain",
    #           "SiteDomain"
    #         ],
    #         [
    #           "link",
    #           "Site"
    #         ],
    #         [
    #           "links",
    #           "Site"
    #         ],
    #         [
    #           "location",
    #           "WGS84GeoPoint"
    #         ],
    #         [
    #           "title",
    #           "ShortText"
    #         ]
    #       ]
    #     ],
    #     [
    #       [
    #         5
    #       ],
    #       [
    #         [
    #           "_key",
    #           "ShortText"
    #         ],
    #         [
    #           "_nsubrecs",
    #           "Int32"
    #         ]
    #       ],
    #       [
    #         "brazil",
    #         1
    #       ],
    #       [
    #         "korea",
    #         1
    #       ],
    #       [
    #         "usa",
    #         2
    #       ],
    #       [
    #         "china",
    #         2
    #       ],
    #       [
    #         "japan",
    #         3
    #       ]
    #     ]
    #   ]
    # ]

## 4.5.3. ドリルダウン結果の制限

ドリルダウン結果はデフォルト10件に制限されています。 `drilldown_limits` と `drilldown_offset` パラメータをドリルダウン結果をカスタマイズするのに使います。

実行例:

    select --table Site --limit 0 --drilldown country --drilldown_sortby _nsubrecs --drilldown_limit 2 --drilldown_offset 2
    # [
    #   [
    #     0,
    #     1337566253.89858,
    #     0.000355720520019531
    #   ],
    #   [
    #     [
    #       [
    #         9
    #       ],
    #       [
    #         [
    #           "_id",
    #           "UInt32"
    #         ],
    #         [
    #           "_key",
    #           "ShortText"
    #         ],
    #         [
    #           "country",
    #           "SiteCountry"
    #         ],
    #         [
    #           "domain",
    #           "SiteDomain"
    #         ],
    #         [
    #           "link",
    #           "Site"
    #         ],
    #         [
    #           "links",
    #           "Site"
    #         ],
    #         [
    #           "location",
    #           "WGS84GeoPoint"
    #         ],
    #         [
    #           "title",
    #           "ShortText"
    #         ]
    #       ]
    #     ],
    #     [
    #       [
    #         5
    #       ],
    #       [
    #         [
    #           "_key",
    #           "ShortText"
    #         ],
    #         [
    #           "_nsubrecs",
    #           "Int32"
    #         ]
    #       ],
    #       [
    #         "usa",
    #         2
    #       ],
    #       [
    #         "china",
    #         2
    #       ]
    #     ]
    #   ]
    # ]

文字列型のカラムに対するドリルダウンは、他の型でのドリルダウンに比べて低速です。文字列でのドリルダウンを行いたい場合には、このチュートリアルのように、文字列型を主キーとするテーブルを別途作成し、そのテーブルを型とするカラムを作成します。