メインコンテンツへスキップ
メインコンテンツへスキップ

S3 バケット内のデータをクエリする方法

世界中のデータの多くは Amazon S3 バケットに保存されています。 このガイドでは、chDB を使ってそのデータに対してクエリを実行する方法を学びます。

セットアップ

まず仮想環境を作成します。

python -m venv .venv
source .venv/bin/activate

それでは chDB をインストールします。 chDB のバージョンが 2.0.2 以上であることを確認してください。

pip install "chdb>=2.0.2"

それでは、IPython をインストールします:

pip install ipython

このガイドの残りの手順で実行するコマンドは ipython を使います。次のコマンドを実行して ipython を起動してください。

ipython

このコードは Python スクリプトやお使いのノートブックでも使用できます。

S3 バケット内のファイル一覧を取得する

まずは Amazon レビューを含む S3 バケット 内のすべてのファイルを一覧表示してみます。 これを行うには、s3 テーブル関数 を使用し、ファイルへのパス、または複数ファイルにマッチするワイルドカードを引数として指定します。

ヒント

バケット名だけを渡すと、例外がスローされます。

また、ファイルがパースされないように One 入力フォーマットも使用します。これにより、ファイルごとに 1 行だけが返され、_file 仮想カラムからファイルを、_path 仮想カラムからパスを参照できます。

import chdb

chdb.query("""
SELECT
    _file,
    _path
FROM s3('s3://datasets-documentation/amazon_reviews/*.parquet', One)
SETTINGS output_format_pretty_row_numbers=0
""", 'PrettyCompact')
┌─_file───────────────────────────────┬─_path─────────────────────────────────────────────────────────────────────┐
│ amazon_reviews_2010.snappy.parquet  │ datasets-documentation/amazon_reviews/amazon_reviews_2010.snappy.parquet  │
│ amazon_reviews_1990s.snappy.parquet │ datasets-documentation/amazon_reviews/amazon_reviews_1990s.snappy.parquet │
│ amazon_reviews_2013.snappy.parquet  │ datasets-documentation/amazon_reviews/amazon_reviews_2013.snappy.parquet  │
│ amazon_reviews_2015.snappy.parquet  │ datasets-documentation/amazon_reviews/amazon_reviews_2015.snappy.parquet  │
│ amazon_reviews_2014.snappy.parquet  │ datasets-documentation/amazon_reviews/amazon_reviews_2014.snappy.parquet  │
│ amazon_reviews_2012.snappy.parquet  │ datasets-documentation/amazon_reviews/amazon_reviews_2012.snappy.parquet  │
│ amazon_reviews_2000s.snappy.parquet │ datasets-documentation/amazon_reviews/amazon_reviews_2000s.snappy.parquet │
│ amazon_reviews_2011.snappy.parquet  │ datasets-documentation/amazon_reviews/amazon_reviews_2011.snappy.parquet  │
└─────────────────────────────────────┴───────────────────────────────────────────────────────────────────────────┘

このバケットには Parquet ファイルのみが格納されています。

S3 バケット内のファイルをクエリする

次に、これらのファイルに対してどのようにクエリを実行するかを見ていきます。 各ファイルの行数を数えたい場合は、次のクエリを実行できます。

chdb.query("""
SELECT
    _file,
    count() AS count,
    formatReadableQuantity(count) AS readableCount    
FROM s3('s3://datasets-documentation/amazon_reviews/*.parquet')
GROUP BY ALL
SETTINGS output_format_pretty_row_numbers=0
""", 'PrettyCompact')
┌─_file───────────────────────────────┬────count─┬─readableCount───┐
│ amazon_reviews_2013.snappy.parquet  │ 28034255 │ 2803万          │
│ amazon_reviews_1990s.snappy.parquet │   639532 │ 63万9532        │
│ amazon_reviews_2011.snappy.parquet  │  6112495 │ 611万           │
│ amazon_reviews_2015.snappy.parquet  │ 41905631 │ 4190万          │
│ amazon_reviews_2012.snappy.parquet  │ 11541011 │ 1154万          │
│ amazon_reviews_2000s.snappy.parquet │ 14728295 │ 1472万          │
│ amazon_reviews_2014.snappy.parquet  │ 44127569 │ 4412万          │
│ amazon_reviews_2010.snappy.parquet  │  3868472 │ 386万           │
└─────────────────────────────────────┴──────────┴─────────────────┘

S3 バケットの HTTP URI を指定することもでき、その場合も同じ結果が得られます。

chdb.query("""
SELECT
    _file,
    count() AS count,
    formatReadableQuantity(count) AS readableCount    
FROM s3('https://datasets-documentation.s3.eu-west-3.amazonaws.com/amazon_reviews/*.parquet')
GROUP BY ALL
SETTINGS output_format_pretty_row_numbers=0
""", 'PrettyCompact')

これらの Parquet ファイルのスキーマを DESCRIBE 句を使って確認してみましょう。

chdb.query("""
DESCRIBE s3('s3://datasets-documentation/amazon_reviews/*.parquet')
SETTINGS describe_compact_output=1
""", 'PrettyCompact')
    ┌─name──────────────┬─type─────────────┐
 1. │ review_date       │ Nullable(UInt16) │
 2. │ marketplace       │ Nullable(String) │
 3. │ customer_id       │ Nullable(UInt64) │
 4. │ review_id         │ Nullable(String) │
 5. │ product_id        │ Nullable(String) │
 6. │ product_parent    │ Nullable(UInt64) │
 7. │ product_title     │ Nullable(String) │
 8. │ product_category  │ Nullable(String) │
 9. │ star_rating       │ Nullable(UInt8)  │
10. │ helpful_votes     │ Nullable(UInt32) │
11. │ total_votes       │ Nullable(UInt32) │
12. │ vine              │ Nullable(Bool)   │
13. │ verified_purchase │ Nullable(Bool)   │
14. │ review_headline   │ Nullable(String) │
15. │ review_body       │ Nullable(String) │
    └───────────────────┴──────────────────┘

それでは、レビュー数に基づいて上位の商品カテゴリを集計し、あわせて平均星評価も計算してみましょう。

chdb.query("""
SELECT product_category, count() AS reviews, round(avg(star_rating), 2) as avg
FROM s3('s3://datasets-documentation/amazon_reviews/*.parquet')
GROUP BY ALL
LIMIT 10
""", 'PrettyCompact')
    ┌─product_category─┬──reviews─┬──avg─┐
 1. │ おもちゃ         │  4864056 │ 4.21 │
 2. │ アパレル         │  5906085 │ 4.11 │
 3. │ 旅行用品         │   348644 │ 4.22 │
 4. │ キッチン用品     │  4880297 │ 4.21 │
 5. │ 書籍             │ 19530930 │ 4.34 │
 6. │ アウトドア用品   │  2302327 │ 4.24 │
 7. │ 映像             │   380596 │ 4.19 │
 8. │ 食料品           │  2402365 │ 4.31 │
 9. │ 靴               │  4366757 │ 4.24 │
10. │ ジュエリー       │  1767667 │ 4.14 │
    └──────────────────┴──────────┴──────┘

プライベートな S3 バケット内のファイルをクエリする

プライベートな S3 バケット内のファイルをクエリする場合、アクセスキーとシークレットアクセスキーを指定する必要があります。 これらの認証情報は s3 テーブル関数に渡すことができます。

chdb.query("""
SELECT product_category, count() AS reviews, round(avg(star_rating), 2) as avg
FROM s3('s3://datasets-documentation/amazon_reviews/*.parquet', 'access-key', 'secret')
GROUP BY ALL
LIMIT 10
""", 'PrettyCompact')
注記

このクエリはパブリックバケットであるため動作しません。

別の方法として named collections を使用することもできますが、この方法は chDB ではまだサポートされていません。