コースApache Doris Hackathon自分のペースで進めるタスク · いつでも開始 · 登録不要

トラック A · タスク A3

ログ検索 エクスプローラー

すべてを SQL で扱う小さな Kibana を作り、11:40 に注文処理が失敗した原因を調べます。

  • 60~120 分
  • 初心者向け
  • 言語自由 · CLI または Web
  • AI ツールの利用歓迎

困ったときは? 質問はこちら: #dev 参加先: Apache Doris Slack。メンテナーやほかの参加者がサポートします。

1

環境を準備

何を作るか、Doris ならどう簡単になるかを学び、クラスターを起動します。

作成するもの

ログエクスプローラーを作り、障害を解明します。

200,000 行のログ、6 つのサービス、そして問題のあった朝。BM25 の関連度順でキーワード検索し、サービス・レベル・時間で絞り込み、件数を随時計算します。すべて、1 つの Doris テーブルに対する通常の SQL で実行します。

次の機能を持つ小さなログエクスプローラー:

  • 検索用の 検索ボックス (キーワード・フレーズ)と関連度による順位付け、
  • フィルター (サービス、レベル、時間範囲)、
  • ファセット件数 (結果の隣にサービス別・レベル別の件数を表示)、
  • 任意で次も追加: タイムライン (5 分ごとのエラー数)。

最後に実際の調査を行います: 11:40 に注文処理が失敗し始めました。原因となったサービスはどれで、問題は実際にはいつ始まったのでしょうか? エクスプローラーから答えが明確にわかるようにしてください。

概略図作成するもの · ワイヤーフレーム(スクリーンショットではありません)

概略図はコードパネルの上部にあります

Doris で取り組む利点

  • 同じテーブルで検索と分析。 転置インデックスがキーワードクエリを処理し、同じ WHERE 句を次に使います: GROUP BY によるファセット集計。別システムとの同期は不要です。

  • 関連度に基づく順位付け。 score() が BM25 で結果をソートするため、新しい行だけでなく、最も関連する行が先頭に並びます。

  • 低コストなフィルター。 service および level にはそれぞれ転置インデックスがあり、時間範囲はソートキーで絞り込みます。

パネル:テーブル定義のインデックス行

始める前に

  • docker pull apache/doris:all-in-one-4.1.3
  • docker run -d --name doris -p 9030:9030 -p 8030:8030 -p 8040:8040 apache/doris:all-in-one-4.1.3
  • docker exec -it doris mysql -uroot -h127.0.0.1 -P9030
  • curl -LO https://github.com/morningman/demo-env/releases/download/for-hackathon/doris-hackathon-glasgow-2026.zip && unzip doris-hackathon-glasgow-2026.zip && cd doris-hackathon-glasgow-2026
ホスト
127.0.0.1
ポート
9030
ユーザー
rootパスワードなし
データベース
hackathon

データ

hackathon.app_logs :6 つのサービスを 1 つのテーブルに保存します:

テーブルhackathon.app_logs · sql
CREATE TABLE app_logs (  ts          DATETIME(3)  NOT NULL,  service     VARCHAR(32)  NOT NULL,   -- api-gateway, auth, catalog, search, checkout, payment  level       VARCHAR(8)   NOT NULL,   -- DEBUG / INFO / WARN / ERROR  host        VARCHAR(32),  trace_id    VARCHAR(32),  status      INT,                     -- HTTP status, when relevant  latency_ms  INT,  message     STRING       NOT NULL,  INDEX idx_msg (message) USING INVERTED PROPERTIES ("parser" = "english", "support_phrase" = "true"),  INDEX idx_service (service) USING INVERTED,  INDEX idx_level (level) USING INVERTED)DUPLICATE KEY(ts)DISTRIBUTED BY HASH(trace_id) BUCKETS 1PROPERTIES ("replication_num" = "1");

seed/a3_app_logs.sql が生成するデータ: 2026 年 10 月 13 日の 200,000 行 に対し、1 つの INSERT … SELECT … FROM numbers("number" = "200000") で生成します。ダウンロードは不要です。このデータのどこかに障害が潜んでいます。

パネル → テーブル:テーブル定義の全体

AI を使って作る

AI コーディングエージェントとの共同作業を推奨しています。 Doris 4.x の検索機能と AI 機能は、多くのモデルの学習データより新しいため、SQL を書かせる前に適切な情報を渡してください:

  1. 次の コンテキストプロンプト をエージェントに貼り付けます。

  2. 参照先として次を指定: このページに掲載した参考資料 および AGENTS.md (スターターキット内)。多くのコーディングエージェントはこのファイルを自動で読み込みます。

  3. コードに組み込む前に、すべての SQL 文を実際のクラスターで実行させてください。

  4. さらに、次を接続すると便利です: Doris MCP Server (参照: タスク A2)。エージェント自身でスキーマを確認し、クエリをテストできるようになります。

コンテキストプロンプトエージェントに貼り付け
I'm building a log search explorer on Apache Doris 4.1 for a hackathon.Connection: MySQL protocol, 127.0.0.1:9030, user root, empty password, database `hackathon`.Use a plain MySQL driver and raw SQL.Table `app_logs`: ts DATETIME(3), service, level, host, trace_id, status INT, latency_ms INT,message STRING. Inverted indexes on message (english parser, phrase support), service, level.Doris SQL rules:1. Text search: `message MATCH_ANY 'a b'`, `MATCH_ALL`, `MATCH_PHRASE 'a b'`. Never LIKE.2. BM25: `score()` only with a MATCH_* predicate + `ORDER BY score() DESC LIMIT n`,   selected plain (`score() AS relevance`): no ROUND() or JOIN in that SELECT.   Bind the user's search text as a driver parameter.3. score() cannot be used with GROUP BY. For facet counts run a second query with the   same WHERE clause and GROUP BY service, level.4. Time buckets: `minute_floor(ts, 5)`.Build: search box, service/level/time filters, facet counts, and an error timeline.Run every SQL statement against the live cluster first.

AI エージェントが陥りやすい Doris の落とし穴

TrapWhat to do instead
次の使用: LIKE '%term%' によるテキスト検索col MATCH_ANY 'a b' (OR)、 MATCH_ALL (AND)、 MATCH_PHRASE 'a b' 。これらは転置インデックスを使います
次の呼び出し: score() を任意のクエリで使用score() には次が必要: MATCH_* の述語を次に指定: WHERE および ORDER BY score() DESC LIMIT n。指定しないと Doris はクエリを拒否します
丸め、結合、順位付けの対象: score() を同じクエリ内で行う次はそのまま使います: score() AS relevance を単一テーブルのクエリ内でそのまま使います。丸めや結合、 ROW_NUMBER() は外側のクエリで行ってください。次の代わりにサブクエリを使います: WITH CTE
score() を次の内側で使用: GROUP BY / 集約使用できません。ファセットの件数集計には同じ次の条件を再利用します: WHERE を除外: score()
ORM を使う通常の MySQL ドライバーと生の SQL を推奨します。ORM は Doris がサポートしない文を生成する場合があります
2

実装する

6 マイルストーン、 M0 → M5。パネルは読んでいるステップに追従します。

  1. マイルストーン 05 分

    ログを生成

    スターターキットのフォルダー内で実行:

    M0 · ログを生成bash
    docker exec -i doris mysql -uroot -h127.0.0.1 -P9030 < seed/a3_app_logs.sql
    確認ポイント

    数秒後に表示: 200,000 行のログ、開始時刻: 00:00:00 終了時刻: 23:59:59 (10 月 13 日)。

  2. マイルストーン 115 分

    BM25 によるキーワード検索

    M1 · BM25 によるキーワード検索sql
    USE hackathon;SELECT ts, service, level, message, score() AS relevanceFROM app_logsWHERE message MATCH_ANY 'timeout refused'ORDER BY relevance DESCLIMIT 20;

    検索ボックスに接続します。ユーザー入力はドライバーパラメーターで渡します(MATCH_ANY %s); a3/starter.py (スターターキット内)がこの処理を実装しています。

    確認ポイント

    20 件の結果はすべて connection refused の行です。BM25 は出現頻度の低い語を重視します: refused は 68 行に出現し、 timeout は 347 行に出現します。検索語を次だけにすると、 timeout ほかの結果も確認できます。

  3. マイルストーン 215 分

    フィルター

    M2 · フィルターsql
    SELECT ts, service, level, message, score() AS relevanceFROM app_logsWHERE message MATCH_ANY 'timeout'  AND level = 'ERROR'  AND service IN ('checkout', 'payment')  AND ts >= '2026-10-13 11:00:00' AND ts < '2026-10-13 12:30:00'ORDER BY relevance DESCLIMIT 20;
    確認ポイント

    すべての結果は timeout を含む ERROR 行です。2 つのサービスのうち 1 つだけが表示されます。

  4. マイルストーン 315 分

    ファセット件数

    score() は集約できないため、ファセット集計にはこれを除いた同じフィルターを使います:

    M3 · ファセット件数sql
    SELECT service, level, COUNT(*) AS hitsFROM app_logsWHERE message MATCH_ANY 'timeout'  AND ts >= '2026-10-13 11:00:00' AND ts < '2026-10-13 12:30:00'GROUP BY service, levelORDER BY hits DESC;
    確認ポイント

    この時間帯に一致するログは 163 行で、すべて ERRORです。件数の合計は、次を除いた同じ検索の件数と一致する必要があります: GROUP BY。確認コマンド: SELECT COUNT(*) と同じ WHERE.

  5. マイルストーン 415 分

    エラーのタイムライン

    M4 · エラーのタイムラインsql
    SELECT minute_floor(ts, 5) AS bucket, service, COUNT(*) AS errorsFROM app_logsWHERE level = 'ERROR'  AND ts >= '2026-10-13 11:00:00' AND ts < '2026-10-13 12:30:00'GROUP BY bucket, serviceORDER BY bucket, service;
    確認ポイント

    11:35 から 12:00 の間に 2 つのサービスで急増します。それ以外の時間帯では、どのサービスも 5 分間のエラー数が 4 件を超えません。

  6. マイルストーン 5

    障害を解明

    エクスプローラーを使って答えます: 注文処理の失敗を引き起こしたサービスはどれで、何時何分に始まりましたか? 答えと、それを裏付けるクエリを README に記載してください。

3

完成させる

チェックを済ませ、成果を共有し、バッジを獲得しましょう。

完了条件

チェックリスト

提出してバッジを獲得

参加 → 提出 → バッジを獲得。

  1. 成果物は次の名前のフォルダーにまとめてください: ご自身の GitHub ID。コードと README を含め、README に内容、実行方法、スクリーンショットまたは GIF 1 点、使用した Doris の機能を記載します。

  2. プルリクエストを作成 次の場所に追加してください: morningman/demo-env 配置先: doris-hackathon-glasgow-2026/<your-github-id>/。フォークして push するか、GitHub の次の操作を使ってください: Add file → Upload files。ほかに入力する項目はありません。

  3. 共有する 共有先: #dev 参加先: Apache Doris Slack:プルリクエストまたはリポジトリへのリンクと、スクリーンショットまたは短いデモを共有します。質問、提出、バッジの案内はすべてこちらで行います。

タスクに参加した方全員に次のバッジを贈ります: Apache Doris Contributor バッジ。Doris 本体へのプルリクエストがマージされている必要はありません。締め切りはないので、ご自身のペースで進めてください。チーム参加も可能ですが必須ではありません。全員の GitHub ID を次に記載してください: README.

追加の挑戦

  • フレーズ検索と入力補完: MATCH_PHRASE 'connection refused', MATCH_PHRASE_PREFIX を使って入力中に検索します。

  • トレース表示:行をクリックすると、同じ次の値を持つログをすべて表示します: trace_id。時刻順で表示します。

  • クエリ文字列検索:次を試してください: SEARCH() DSL(Lucene 形式の field:term AND …)。参照: SEARCH 関数.

  • ログのリアルタイム追跡:毎秒数行を追加し、自動更新します。

  • インデックスの有無を比較:比較対象: MATCH_ANY ともに歩む LIKE '%timeout%' を全テーブルで実行し、所要時間を表示します。

トラブルシューティングと参考資料

SymptomFix
docker: command not found (macOS)Docker Desktop を起動してください。起動済みなら CLI へのリンクを作成します: sudo ln -s /Applications/Docker.app/Contents/Resources/bin/docker /usr/local/bin/docker
error getting credentials (イメージ取得時)削除する項目: credsStore のフィールドを次から削除: ~/.docker/config.json (ローカル開発環境のみ)
port is already allocated別のプロセス(多くは別の Doris)が 9030、8030、8040 のいずれかを使っています。実行中のコンテナーを確認してください(docker ps)。または別のホストポートを公開します。例: -p 19030:9030。その場合は 19030 に接続してください。
The container name "/doris" is already in use以前に起動したことがあります: docker start doris。最初からやり直すには、 docker rm -f doris (データが削除されます)
コンテナーが終了する、または状態が変わらない: (healthy)確認: docker logs doris。多くはメモリが原因です。Docker Desktop に 6 GB 以上を割り当ててください(Settings → Resources)。Apple Silicon では次を追加しないでください: --platform linux/amd64
permission denied: ./doris.sh解凍ツールによって実行権限が失われています: chmod +x doris.sh、または次を実行: bash doris.sh start
Current database is not set実行: USE hackathon; を先に実行するか、次で接続します: -Dhackathon
score() function requires WHERE clause with MATCH function, ORDER BY and LIMIT次を追加: MATCH_* の述語、 ORDER BY score() DESC および LIMIT、さらに次は score() を式で包まないでください(上記の落とし穴を参照)
10 分以上解決できない場合投稿先: #dev 参加先: Apache Doris Slack

参考資料

全文検索BM25転置インデックスSEARCH 関数

Apache Doris Hackathon

すべてのタスク

コースに戻る
  1. A160~120 分ハイブリッド検索アプリ課題の概要を開く
  2. A245~90 分MCP で Doris に質問課題の概要を開く
  3. A360~120 分ログ検索エクスプローラー現在位置
  4. A460~120 分エージェントトレースエクスプローラー課題の概要を開く
  5. B30~60 分トラック B · ドキュメントからデモへ課題の概要を開く