参考文献 / アーカイブと連携機能
Telegram · 全文検索
保存されたメッセージを、単語の形態、完全なフレーズ、ドメイン、@ユーザー名で検索し、署名付きジャーナルに紐付けられたインデックスを用いて、最も一致度の高いものから順に表示します。
アーカイブの分析 · ローカルでのOCRおよび文字起こし · Wiki
プレビュー。「ジャーナル」で、検索フィールドの横にある「最良の一致・語形」を選択します。 結果はBM25でランク付けされ、同じ単語の他の語形とも一致します。 たとえば、「перевод」と入力すると「переводом」や「переводы」が、「transfer」と入力すると「transfers」が検索され、中国語の フレーズはスペースなしで検出されます。「最新順・完全一致」を選択すると、レコード全体に対する以前の 部分文字列検索が維持されます。
インデックスは派生データです。これは署名付きジャーナルから再構築されるものであり、それ自体は決して署名されず、 エクスポート対象にもなりません。元の記録は変更されません。
検索構文#
| 執筆 | 検索 |
|---|---|
перевод карта |
両方の単語を含む記録(形式は問わない) |
"переводом на карту" |
この順序で、この正確なフレーズを記載してください。 |
бонус OR подарок |
どちらの単語でも可 |
перевод -казино |
除外語を含まない記録 |
example.com |
ドメインおよびそのサブドメイン(隠しリンクやボタンのURL内にあるものも含む) |
@username, t.me/username |
当該アカウントのメンションやリンク、およびそのアカウントが送信したメッセージ |
#tag |
ハッシュタグ |
+79991234567、ウォレットアドレス、メールアドレス |
テキストまたはリンクで同じ値を記載 |
from:@username, from:123456 |
その送信者からのメッセージ |
chat:-1001234567890 |
チャットは1つ。アクセス権限を制限できるのは自分自身のもののみです。 |
id:42 |
メッセージ42の保存済みバージョン |
since:2026-01-01 until:2026-01-31 |
観測期間:時刻を含まない日付は、その1日全体を指します |
kind:edited |
編集のみ(new, snapshot, edited, recovered) |
source:ocr, source:transcription, source:all |
メッセージの代わりに、またはメッセージと共に認識されたテキスト |
他の単語が存在する場合、前置詞やその他の機能語は無視されます。 単語内に混在する類似文字(キリル文字の単語内のラテン文字の「a」など)、全角 および装飾用ユニコード文字、ならびに不可視文字は正規化されます。
言語#
言語は、各レコードのスクリプトや文字列から検出されます:
| スクリプト | 一致 |
|---|---|
| キリル文字 | pymorphy3 を使用したロシア語およびウクライナ語の語幹抽出。オプションのウクライナ語辞書を使用しない場合は、軽量なウクライナ語ステマーが使用されます。 |
| ラテン語 | 英語のSnowballステマーを使用。発音区別符号は無視する |
| 中国語、日本語、韓国語、タイ語、ラオス語、クメール語、ミャンマー語 | 重複する文字ペア:スペースを含まない任意のフレーズが検出されます。中国語のクエリは、jieba を使用して単語ごとに分割されます。 |
| その他のスクリプト | 正確な表現 |
ウクライナ語辞書(pymorphy3-dicts-uk)はGPL-3.0の下で配布されているため、
デフォルトではインストールされません。以下のコマンドでインストールしてください pip install "tgwitness[uk-dictionary]";
インデックスが新しいアナライザーを認識し、自動的に再構築されます。
インデックスの保存場所#
| モード | 保存 | 使用方法 |
|---|---|---|
| ディスク上(デフォルト) | search/fulltext.sqlite3 ワークスペースディレクトリ内 |
大規模なアーカイブに対応。再起動後もデータが保持されます。 |
| メモリ内のみ | ディスク上には何も保存されず、起動のたびに再構築される | ディスク上にメッセージ本文の派生コピーは保存しない |
| オフ | インデックスなし;新しい順 · テキストはそのまま保持 | 最小限のインストール環境 |
メイン管理者は、各ワークスペースについて、「ジャーナル」→「フィルター」→「検索インデックス」
でモードを選択します。 TGWITNESS_FULLTEXT=disk|memory|off 独自の設定がないワークスペースの
デフォルト値を設定します。「メモリ」または「オフ」に切り替えると、ファイルが削除されます。
インデックスファイルはジャーナルと同じ保護措置が適用されており、プライベートデータ
ディレクトリ内に格納されます。暗号化はされておらず、バックアップやオフサイトのコピーには含まれません。
新しい記録は数秒以内にバックグラウンドでインデックス化されます。検索時には まず直近の未処理データがインデックス化されるため、ほんの少し前に保存された記録も検索結果に表示されます。既存の日誌は 更新後にインデックス化されますが、その間もパネルの動作はブロックされません。インデックス化が完了するまでは、検索結果は インデックス化済みの記録のみを対象とし、日誌には進行状況が表示されます。インデックスの再構築は 最初の記録から再度開始されます。
python -m tgwitness index status --data-dir data/live
python -m tgwitness index rebuild --data-dir data/live --json
rebuild パネルを停止する必要があります(そうでない場合は終了コード 3)。 --json、
標準出力には結果のみが表示され、進行状況は標準エラーに出力されます。
結果と署名付きジャーナル#
インデックスには、対象となる最新のジャーナルレコードのシーケンス番号とハッシュが保存されており、 ジャーナルを開く際にそれらと照合を行います。ジャーナルが置き換えられたり、復元されたり、編集されたりすると、 インデックスが再構築されます。すべてのレスポンスでこの位置情報が報告され、すべてのヒットは シーケンス番号に基づいて署名付きジャーナルから読み戻されます。インデックスは、どの レコードをどの順序で表示するかを決定しますが、その内容を決することは決してありません。チャットへのアクセスは、 インデックスの内容ではなく、ジャーナル自体のチャットフィールドに対して行われます。
認識されたテキスト#
OCRデータと文字起こしデータは、暗号化されたアーティファクト内に保持されます。それらのインデックスは
メモリ内にのみ存在し、認識ジョブが完了すると再構築されます。一致した項目は、
media.saved レコード上に「機械認識」というラベルとともに表示され、エンジン、モデル、および
抜粋が記載されます。Telegramで送信されたテキストとして表示されることは決してありません。この同じインデックスは
「認識済みテキストの検索」機能にも利用され、プレーンな部分文字列との照合も引き続き可能です。
アクセス#
チャット範囲のアクセスでは、そのチャットからの記録のみが検出されます。これには、
添付ファイルの認識されたテキストも含まれます。 chat: その他のフィルターは、その範囲を絞り込むことしかできません。スコープ付きアクセスに表示されるインデックスのステータスには、
ジャーナルの合計件数は含まれません。モードの変更やインデックスの再構築は、
メイン管理者のみが実行できます。
アーカイブおよびMCPに問い合わせる#
アーカイブへの問い合わせは、インデックスの構築が完了すると、このインデックスからソースを取得します。 選択されたチャット全体から最も一致度の高い結果が返され、保存済みのテキストは1回のみカウントされます。最大24件の ソースが送信されます。長いテキストは一致箇所を境に切り詰められ、切り詰められたものとしてマークされます。 最近の変更に関する問い合わせ、1つのメッセージの保存済みバージョン、および インデックスの構築中の検索については、以前の時系列順の取得方法が使用されます。プレビューには どの方法が使用されたかが表示されます。
MCPクライアントは以下を呼び出すことができます search_messages と ranked=true で呼び出し、
next_offsetでページングを行うことができます。スコープ指定された接続では、自身のチャットのみを受信します。
順位付きページネーションは、ページサイズにかかわらず、最大で最初の1,000件の結果を対象とします。さらに一致する項目を確認するには、クエリ、チャット、または期間を絞り込んでください。「新しい順」検索では、各ページを選択する前に、メッセージ、OCR結果、および文字起こし結果が新しい順に並べ替えられます。
依存関係#
| パッケージ | ライセンス | 理由 |
|---|---|---|
| pymorphy3、pymorphy3-dicts-ru、DAWG2-Python | MIT | ロシア語およびウクライナ語の語幹;辞書はローカルに読み込まれます |
| snowballstemmer | BSD-3条項 | 英語の語幹、純粋なPython |
| jieba | MIT | 中国語のクエリのセグメンテーション、純粋なPython(ソースコードのみの配布) |
| pymorphy3-dicts-uk(任意) | GPL-3.0 | ウクライナ語の完全な辞書 |
SQLite FTS5 を使用するには、 unicode61 tokenizer が必要です。これは、
現在の Python ビルドに含まれる SQLite の一部です。これがなければ、ベストマッチ検索は「利用不可」と報告します。
ベンチマーク#
python tools/bench_fulltext.py --messages 1000000 --work <empty directory>200のチャットに含まれる、リンクやハンドルを含むロシア語、ウクライナ語、英語、
中国語、日本語のメッセージが混在する確定的な署名付きジャーナルを作成し、インデックスを構築し、
一般的な検索の所要時間を測定します(50件の結果、7回の実行における中央値)。
測定環境:Windows 11、Intel Core i9-13900K、128 GB RAM、Python 3.12.10、SQLite
3.49.1、データは exFAT ドライブに保存、アナライザー fulltext-v1+pymorphy3-ru+light-uk+snowball-en:
| 測定 | 結果 |
|---|---|
| 署名付きジャーナル | 1,000,000件のメッセージ、1.50 GiB、19分で書き込み完了 |
| ジャーナルからのインデックス構築 | 71秒、秒間約14,141メッセージ |
| インデックスファイル | 58 MiB、ジャーナルの 3.8% |
| 新しいレコードの直後に検索 | 中央値 8 ms、P95 9 ms |
| 以前の部分文字列検索、同じジャーナル | перевод 3.2 秒、 银行转账 2.6秒, verify-account.example 2.6秒 |
| 検索 | 一致するレコード | 最良の一致、中央値 | p95 | 新しい順、中央値順 |
|---|---|---|---|---|
一般的な単語、語形: перевод |
134,403 | 82 ms | 85 ms | 7 ms |
2つの単語: оплата карта |
28,996 | 43 ms | 43 ms | 14 ms |
珍しい単語: розыгрыш подарок |
28,881 | 42 ms | 47 ms | 13 ms |
正確なフレーズ: "переказ коштів на картку" |
カウント対象外 | 35 ms | 36 ms | 6 ms |
ドメインとサブドメイン: verify-account.example |
12,435 | 17 ms | 17 ms | 3 ms |
@username: @support_desk_bot |
10,331 | 15 ms | 16 ms | 3 ms |
スペースなしの中国語: 银行转账 |
17,691 | 23 ms | 24 ms | 3 ms |
日本語: リンク |
16,603 | 23 ms | 25 ms | 3 ms |
英語の語幹: withdrawal |
27,775 | 26 ms | 26 ms | 2 ms |
ORおよび除外条件: бонус OR подарок -казино |
268,034 | 190 ms | 193 ms | 19 ms |
チャットフィルター: chat:-1000000000007 перевод |
652 | 9 ms | 9 ms | 6 ms |
期間フィルター: since:2026-01-01 until:2026-01-31 выплата |
115,732 | 155 ms | 156 ms | 81 ms |
特定のフレーズは、ページが 満杯になるまで候補に対して文字通り順に照合されるため、その合計はカウントされません。所要時間は一致するレコードの数に比例して増加します。 チャットや期間を絞り込むと、広範囲な検索が高速化されます。合成コーパスでは 語彙数が限られているため、一般的な単語は実際のチャットに比べてはるかに多くのレコードと一致します。