Справочник / Архив и интеграции
Полнотекстовый поиск по архиву Telegram
Поиск сохраненных сообщений по формам слов, точным фразам, доменам и @именам пользователей, с отображением наиболее подходящих результатов в первую очередь, при этом индекс привязан к подписанному журналу.
TgWitness / Документация · Расследование
Анализ архива · Локальное распознавание текста (OCR) и транскрипция · Вики
Предварительный просмотр. В разделе «Журнал» выберите «Лучшее совпадение · формы слова» рядом с полем поиска. Результаты ранжируются по алгоритму BM25 и включают другие формы того же слова: «перевод» находит «переводом» и «переводы», «transfer» находит «transfers», китайская фраза находит без пробелов. «Сначала новые · точный текст» сохраняет предыдущий поиск подстроки по всей записи.
Индекс представляет собой производные данные. Он воссоздаётся на основе подписанного журнала, сам по себе никогда не подписывается и никогда не попадает в экспорт. Исходные записи не изменяются.
На этой странице
Синтаксис поиска#
| Написать | Найти |
|---|---|
перевод карта |
Записи, содержащие оба слова в любой форме |
"переводом на карту" |
Точная фраза, именно в таком порядке |
бонус OR подарок |
Любое из этих слов |
перевод -казино |
Записи без исключённого слова |
example.com |
Домен и его субдомены, в том числе в скрытых ссылках и URL-адресах кнопок |
@username, t.me/username |
Упоминания и ссылки на аккаунт, а также отправленные им сообщения |
#tag |
Хэштег |
+79991234567, адрес кошелька, адрес электронной почты |
Одно и то же значение в тексте или ссылках |
from:@username, from:123456 |
Сообщения от этого отправителя |
chat:-1001234567890 |
Один чат; он может ограничить только ваш собственный доступ |
id:42 |
Сохраненные версии сообщения № 42 |
since:2026-01-01 until:2026-01-31 |
Период наблюдения; дата без указания времени охватывает весь день |
kind:edited |
Только правки (new, snapshot, edited, recovered) |
source:ocr, source:transcription, source:all |
Распознанный текст вместо сообщений или вместе с ними |
Предлоги и другие служебные слова игнорируются при наличии других слов. Похожие буквы, входящие в состав слова (например, латинская буква «a» в кириллическом слове), полноширинные и декоративные символы Unicode, а также невидимые символы нормализуются.
Языки#
Язык определяется для каждой записи на основе используемого скрипта и букв:
| Скрипт | Соответствие |
|---|---|
| Кириллица | Русские и украинские леммы с помощью 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#
Запрос в архив извлекает источники из этого индекса, когда он будет готов: наилучшие совпадения по выбранным чатам, при этом сохраненный текст учитывается один раз. Отправляется до 24 источников; длинные тексты обрезаются вокруг места совпадения и помечаются как усеченные. Запросы о последних изменениях, сохраненных версиях одного сообщения и поиски, пока индекс ещё формируется, используют предыдущий хронологический поиск. В предварительном просмотре указывается, какой метод был использован.
Клиенты 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 токеннизатором; он входит в состав SQLite в
текущих сборках Python. Без него при поиске по наилучшему совпадению выдается сообщение о его недоступности.
Тестирование производительности#
python tools/bench_fulltext.py --messages 1000000 --work <empty directory>создаёт детерминированный подписанный журнал, содержащий смешанные сообщения на русском, украинском, английском,
китайском и японском языках со ссылками и хендлами из 200 чатов, формирует индекс
и измеряет время выполнения типичных поисковых запросов (50 результатов, медиана по 7 запусков).
Тестирование проводилось на Windows 11, Intel Core i9-13900K, 128 ГБ ОЗУ, Python 3.12.10, SQLite
3.49.1, данные на диске с файловой системой exFAT, анализатор fulltext-v1+pymorphy3-ru+light-uk+snowball-en:
| Мера | Результат |
|---|---|
| Подписанный журнал | 1 000 000 сообщений, 1,50 ГиБ, записано за 19 минут |
| Создание индекса на основе журнала | 71 с, около 14 141 сообщений в секунду |
| Файл индекса | 58 МБ, 3,8 % журнала |
| Поиск сразу после появления новой записи | Медиана — 8 мс, p95 — 9 мс |
| Предыдущий поиск подстроки, тот же журнал | перевод 3,2 с, 银行转账 2,6 с, verify-account.example 2,6 с |
| Поиск | Сопоставление записей | Наилучшее соответствие, медиана | p95 | Сначала самые новые, по медиане |
|---|---|---|---|---|
Общие слова, формы слов: перевод |
134,403 | 82 мс | 85 мс | 7 мс |
Два слова: оплата карта |
28,996 | 43 мс | 43 мс | 14 мс |
Редкое слово: розыгрыш подарок |
28,881 | 42 мс | 47 мс | 13 мс |
Точная фраза: "переказ коштів на картку" |
не учитывается | 35 мс | 36 мс | 6 мс |
Домен с поддоменами: verify-account.example |
12,435 | 17 мс | 17 мс | 3 мс |
@username: @support_desk_bot |
10,331 | 15 мс | 16 мс | 3 мс |
Китайский без пробелов: 银行转账 |
17,691 | 23 мс | 24 мс | 3 мс |
Японский: リンク |
16,603 | 23 мс | 25 мс | 3 мс |
Английская основа: withdrawal |
27,775 | 26 мс | 26 мс | 2 мс |
ИЛИ и исключения: бонус OR подарок -казино |
268,034 | 190 мс | 193 мс | 19 мс |
Фильтр чатов: chat:-1000000000007 перевод |
652 | 9 мс | 9 мс | 6 мс |
Фильтр по периоду: since:2026-01-01 until:2026-01-31 выплата |
115,732 | 155 мс | 156 мс | 81 мс |
Точная фраза проверяется буквально по кандидатам в порядке ранжирования до тех пор, пока страница не заполнится, поэтому её итог не учитывается. Время выполнения растёт с увеличением количества совпадающих записей; сужение диапазона чатов или периода ускоряет широкий поиск. В синтетическом корпусе повторяется небольшой словарный запас, поэтому распространённые слова дают гораздо больше совпадений, чем в реальных чатах.