# Telegram · การค้นหาข้อความเต็ม

Canonical page: https://phishdestroy.github.io/TgWitness/th/docs/reference/search/

ค้นหาข้อความที่บันทึกไว้ตามรูปแบบคำ วลีที่ตรงกันเป๊ะ โดเมน และ @usernames โดยแสดงผลลัพธ์ที่ตรงกันมากที่สุดก่อน พร้อมทั้งดัชนีที่เชื่อมโยงกับบันทึกที่ลงนามแล้ว

[Project context and measured scale](https://phishdestroy.github.io/TgWitness/docs/reference/overview/)

[Documentation index](https://phishdestroy.github.io/TgWitness/th/llms.txt)

ค้นหาข้อความที่บันทึกไว้ตามรูปแบบคำ วลีที่ตรงกันเป๊ะ โดเมน และ @usernames โดยแสดงผลลัพธ์ที่ตรงกันมากที่สุดก่อน พร้อมทั้งดัชนีที่เชื่อมโยงกับบันทึกที่ลงนามแล้ว

[TgWitness](https://github.com/phishdestroy/TgWitness/blob/main/README.md) / [เอกสารประกอบ](https://github.com/phishdestroy/TgWitness/blob/main/docs/README.md) · [การสอบสวน](https://phishdestroy.github.io/TgWitness/th/docs/reference/investigation/)

![การสอบสวน](https://phishdestroy.github.io/TgWitness/assets/chapter-investigate.svg)

[การวิเคราะห์ข้อมูลในคลัง](https://phishdestroy.github.io/TgWitness/th/docs/reference/analysis/) · [OCR และแปลงข้อความเป็นข้อความแบบท้องถิ่น](https://phishdestroy.github.io/TgWitness/th/docs/reference/media-analysis/) · [Wiki](https://github.com/phishdestroy/TgWitness/blob/main/docs/wiki/Archive-and-Integrations.md)

**ดูตัวอย่าง** ใน **Journal** ให้เลือก "**Best match · word forms**" ข้างช่องค้นหา ผลลัพธ์จะถูกจัดอันดับด้วย BM25 และจับคู่กับรูปแบบอื่น ๆ ของคำเดียวกัน: *"перевод"* จะพบ *"переводом"* และ *"переводы"*, *"transfer"* จะพบ *"transfers"*, และวลีภาษาจีน จะถูกค้นหาโดยไม่เว้นวรรค **"Newest first · exact text"** จะคงการค้นหา ส่วนย่อยของข้อความจากครั้งก่อนไว้บนบันทึกทั้งหมด

ดัชนีเป็นข้อมูลที่สร้างขึ้นใหม่ โดยถูกสร้างขึ้นใหม่จากบันทึกที่ลงนามแล้ว ไม่เคยถูกลงนาม ด้วยตัวเอง และไม่เคยถูกส่งออกเลย บันทึกต้นฉบับไม่เปลี่ยนแปลง

**บนหน้านี้**

- [ไวยากรณ์การค้นหา](https://phishdestroy.github.io/TgWitness/th/docs/reference/search/#search-syntax)
- [ภาษา](https://phishdestroy.github.io/TgWitness/th/docs/reference/search/#languages)
- [ตำแหน่งของดัชนี](https://phishdestroy.github.io/TgWitness/th/docs/reference/search/#where-the-index-lives)
- [ผลลัพธ์ และบันทึกที่ลงนาม](https://phishdestroy.github.io/TgWitness/th/docs/reference/search/#results-and-the-signed-journal)
- [ข้อความที่ได้รับการระบุ](https://phishdestroy.github.io/TgWitness/th/docs/reference/search/#recognized-text)
- [Access](https://phishdestroy.github.io/TgWitness/th/docs/reference/search/#access)
- [สอบถามข้อมูลจากคลังข้อมูลและ MCP](https://phishdestroy.github.io/TgWitness/th/docs/reference/search/#ask-the-archive-and-mcp)
- [การพึ่งพา](https://phishdestroy.github.io/TgWitness/th/docs/reference/search/#dependencies)
- [Benchmark](https://phishdestroy.github.io/TgWitness/th/docs/reference/search/#benchmark)

## ไวยากรณ์การค้นหา

| เขียน | ผลการค้นหา |
| --- | --- |
| `перевод карта` | บันทึกที่มีคำทั้งสองคำอยู่ด้วย ในรูปแบบใดก็ตาม |
| `"переводом на карту"` | ใช้คำวลีนี้ตามลำดับที่ระบุไว้ |
| `бонус 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](https://github.com/no-plagiarism/pymorphy3) โดยหากไม่ใช้พจนานุกรมภาษายูเครนแบบเลือกได้ จะใช้ตัวแยกคำรากภาษายูเครนแบบเบา |
| ภาษาละติน | ตัวแยกคำแบบ Snowball ภาษาอังกฤษ; เครื่องหมายเสียงถูกเพิกเฉย |
| ภาษาจีน, ภาษาญี่ปุ่น, ภาษาเกาหลี, ภาษาไทย, ภาษาลาว, ภาษาเขมร, ภาษาพม่า | คู่ตัวอักษรที่ทับซ้อนกัน: ทุกวลีจะถูกค้นหาโดยไม่เว้นช่องว่าง คำสั่งภาษาจีนจะถูกแบ่งเป็นคำด้วย jieba |
| สคริปต์อื่น ๆ | คำที่ตรงตามต้นฉบับ |

พจนานุกรมภาษายูเครน (`pymorphy3-dicts-uk`) ถูกแจกจ่ายภายใต้ใบอนุญาต GPL-3.0 ดังนั้นจึง ไม่ถูกติดตั้งโดยค่าเริ่มต้น ให้ติดตั้งด้วย `pip install "tgwitness[uk-dictionary]"`; ดัชนีจะตรวจพบตัววิเคราะห์ใหม่และสร้างตัวเองขึ้นใหม่

## ตำแหน่งของดัชนี

| โหมด | พื้นที่จัดเก็บ | การใช้งาน |
| --- | --- | --- |
| บนดิสก์ (ค่าเริ่มต้น) | `search/fulltext.sqlite3` ในไดเรกทอรี workspace | ไฟล์เก็บถาวรขนาดใหญ่; ยังคงอยู่แม้จะรีสตาร์ทระบบ |
| เก็บไว้ในหน่วยความจำเท่านั้น | ไม่มีข้อมูลใดๆ บนดิสก์; สร้างใหม่ทุกครั้งที่เริ่มต้น | ไม่มีการคัดลอกข้อความที่ดัดแปลงไว้บนดิสก์ |
| ปิด | ไม่มีดัชนี; **แสดงตามลำดับจากใหม่ที่สุด · ข้อความต้นฉบับ**ยังคงอยู่ | การติดตั้งแบบขั้นต่ำ |

ผู้ดูแลระบบหลักจะเลือกโหมดภายใต้ **Journal → Filters → Search index** สำหรับแต่ละพื้นที่ทำงาน `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` ต้องหยุดการทำงานของ panel (หากไม่หยุด จะให้รหัสออก 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-Clause | รากคำภาษาอังกฤษ, Python บริสุทธิ์ |
| jieba | MIT | การแบ่งส่วนคำค้นหาภาษาจีน, Python บริสุทธิ์ (แจกจ่ายเฉพาะโค้ดต้นฉบับ) |
| pymorphy3-dicts-uk (ไม่จำเป็น) | GPL-3.0 | พจนานุกรมภาษายูเครนฉบับสมบูรณ์ |

SQLite FTS5 พร้อมด้วย `unicode61` tokenizer เป็นสิ่งจำเป็น; มันเป็นส่วนหนึ่งของ SQLite ใน เวอร์ชัน Python ปัจจุบัน หากไม่มีมัน ระบบค้นหาที่ตรงกันมากที่สุดจะรายงานว่าไม่สามารถใช้งานได้

## Benchmark

`python tools/bench_fulltext.py --messages 1000000 --work <empty directory>`สร้างบันทึกที่ลงนามแบบกำหนดได้ ซึ่งประกอบด้วยข้อความผสมระหว่างภาษารัสเซีย ยูเครน อังกฤษ จีน และญี่ปุ่น พร้อมด้วยลิงก์และแฮนเดิลใน 200 ห้องสนทนา สร้างดัชนี และวัดเวลาการค้นหาทั่วไป (50 ผลลัพธ์, ค่ามัธยฐานจากการทดสอบ 7 ครั้ง)

ทดสอบบน Windows 11, Intel Core i9-13900K, RAM 128 GB, 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 วินาที |

| ค้นหา | บันทึกที่ตรงกัน | ผลลัพธ์ที่ตรงกันมากที่สุด, ค่ามัธยฐาน | หน้า 95 | แสดงรายการใหม่ที่สุดก่อน, ค่ามัธยฐาน |
| --- | --- | --- | --- | --- |
| คำทั่วไป, รูปแบบของคำ: `перевод` | 134,403 | 82 ms | 85 ms | 7 ms |
| สองคำ: `оплата карта` | 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 |

วลีที่ตรงกันจะถูกตรวจสอบตามตัวอักษรบนผลลัพธ์ที่จัดเรียงตามลำดับความสำคัญจนกว่าหน้าจะ เต็ม ดังนั้นผลรวมจึงไม่ถูกนับ เวลาที่ใช้จะเพิ่มขึ้นตามจำนวนบันทึกที่ตรงกัน; การจำกัดการค้นหาให้แคบลง เช่น การเลือกแชทหรือช่วงเวลาเฉพาะ จะทำให้การค้นหาแบบกว้างเร็วขึ้น คอร์ปัสสังเคราะห์นี้ใช้ คำศัพท์จำนวนน้อยซ้ำๆ ดังนั้นคำทั่วไปจะตรงกับบันทึกได้มากกว่าการแชทจริง
