247 lines
4.8 KiB
Markdown
247 lines
4.8 KiB
Markdown
# 4.OpenSearch-Index-Search-Playbook.md
|
||
|
||
> Tài liệu này kế thừa trực tiếp các file trước (1–3). Mục tiêu: thiết kế **Index & Search Layer** đảm bảo tra cứu nhanh, đúng quyền, hỗ trợ full‑text, semantic search và RAG về sau. Nội dung viết để **tái sử dụng lâu dài**, có thể nạp lại để tiếp tục triển khai.
|
||
|
||
---
|
||
|
||
## Mục lục
|
||
1. Vai trò của Index/Search trong pipeline
|
||
2. Nguyên tắc thiết kế
|
||
3. Kiến trúc logical của Search Layer
|
||
4. Thiết kế Index (mapping chi tiết)
|
||
5. ACL‑aware indexing & filtering
|
||
6. Full‑text Search
|
||
7. Vector & Semantic Search
|
||
8. Hybrid Search (khuyến nghị)
|
||
9. Highlight, Ranking & Relevance tuning
|
||
10. Query contract (API level)
|
||
11. Performance & Scale
|
||
12. Lifecycle management (update/delete)
|
||
13. Checklist triển khai
|
||
|
||
---
|
||
|
||
## 1. Vai trò của Index/Search trong pipeline
|
||
|
||
```text
|
||
Extraction & Chunking
|
||
│
|
||
▼
|
||
Index Layer (OpenSearch)
|
||
│
|
||
▼
|
||
Search UI / Chat (RAG)
|
||
```
|
||
|
||
Index/Search chịu trách nhiệm:
|
||
- Lưu trữ **chunk nội dung + metadata + ACL**
|
||
- Trả kết quả **nhanh, chính xác, đúng quyền**
|
||
- Cho phép search theo **từ khóa lẫn ngữ nghĩa**
|
||
|
||
---
|
||
|
||
## 2. Nguyên tắc thiết kế
|
||
|
||
1. **Chunk‑first, không file‑first**
|
||
2. **Permission filter ở query time nhưng dữ liệu đã chuẩn hóa từ ingestion**
|
||
3. **Hybrid search mặc định** (keyword + vector)
|
||
4. **Index schema ổn định**, embedding thay đổi được
|
||
5. **Re‑index được từ output Extraction mà không cần SharePoint**
|
||
|
||
---
|
||
|
||
## 3. Kiến trúc logical của Search Layer
|
||
|
||
```text
|
||
OpenSearch Cluster
|
||
├── text index
|
||
├── vector index (hoặc combined)
|
||
├── analyzer (vi, en)
|
||
└── ACL filter
|
||
```
|
||
|
||
Có thể:
|
||
- Dùng **1 index combined** (text + vector)
|
||
- Hoặc **2 index song song** (đơn giản giai đoạn đầu: 1 index)
|
||
|
||
---
|
||
|
||
## 4. Thiết kế Index (Mapping)
|
||
|
||
### 4.1 Document unit
|
||
Mỗi document trong index = **1 chunk**.
|
||
|
||
### 4.2 Mapping gợi ý
|
||
|
||
```json
|
||
{
|
||
"mappings": {
|
||
"properties": {
|
||
"chunk_id": { "type": "keyword" },
|
||
"file_id": { "type": "keyword" },
|
||
"file_name": { "type": "text" },
|
||
"text": {
|
||
"type": "text",
|
||
"analyzer": "standard",
|
||
"search_analyzer": "standard"
|
||
},
|
||
"embedding": {
|
||
"type": "knn_vector",
|
||
"dimension": 768
|
||
},
|
||
"site_id": { "type": "keyword" },
|
||
"page_from": { "type": "integer" },
|
||
"page_to": { "type": "integer" },
|
||
"source_url": { "type": "keyword" },
|
||
"permissions": { "type": "keyword" },
|
||
"updated_at": { "type": "date" }
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 5. ACL‑aware Indexing & Filtering
|
||
|
||
### 5.1 Nguyên tắc
|
||
- Không index public rồi filter payload
|
||
- Mỗi chunk mang theo **list principal IDs** (user/group)
|
||
|
||
### 5.2 Filter tại query
|
||
```json
|
||
{
|
||
"terms": {
|
||
"permissions": ["current_user_id", "group_id_1"]
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 6. Full‑text Search
|
||
|
||
Sử dụng khi:
|
||
- Tìm chính xác điều khoản, mã số, tên riêng
|
||
|
||
Ví dụ query:
|
||
```json
|
||
{
|
||
"match": {
|
||
"text": "hợp đồng lao động không xác định thời hạn"
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 7. Vector & Semantic Search
|
||
|
||
Sử dụng khi:
|
||
- Câu hỏi tự nhiên
|
||
- Nội dung diễn đạt khác từ khóa
|
||
|
||
```json
|
||
{
|
||
"knn": {
|
||
"embedding": {
|
||
"vector": [ ... ],
|
||
"k": 10
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 8. Hybrid Search (Khuyến nghị mặc định)
|
||
|
||
```json
|
||
{
|
||
"bool": {
|
||
"must": [
|
||
{
|
||
"match": { "text": "chấm dứt hợp đồng" }
|
||
}
|
||
],
|
||
"should": [
|
||
{
|
||
"knn": {
|
||
"embedding": {
|
||
"vector": [ ... ],
|
||
"k": 10
|
||
}
|
||
}
|
||
}
|
||
]
|
||
}
|
||
}
|
||
```
|
||
|
||
Score cuối = combine(keyword_score, semantic_score)
|
||
|
||
---
|
||
|
||
## 9. Highlight, Ranking & Relevance
|
||
|
||
### 9.1 Highlight
|
||
- Highlight ở field `text`
|
||
- Trả snippet cho UI
|
||
|
||
### 9.2 Ranking hints
|
||
- Boost theo:
|
||
- page proximity
|
||
- recency (updated_at)
|
||
- heading match
|
||
|
||
---
|
||
|
||
## 10. Query Contract (API nội bộ)
|
||
|
||
### POST /search
|
||
Input:
|
||
```json
|
||
{ "query": "...", "user_id": "...", "groups": ["..."] }
|
||
```
|
||
|
||
Output:
|
||
```json
|
||
{
|
||
"results": [
|
||
{ "file_name": "...", "page": 5, "snippet": "...", "url": "..." }
|
||
]
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 11. Performance & Scale
|
||
|
||
- Index theo chunk, không theo file
|
||
- Shard theo dữ liệu, không theo tenant sớm
|
||
- Cache query phổ biến
|
||
|
||
---
|
||
|
||
## 12. Lifecycle Management
|
||
|
||
| Event | Action |
|
||
|------|-------|
|
||
| File update | Delete chunks cũ → index lại |
|
||
| File delete | Soft delete hoặc remove |
|
||
| Re‑embedding | Update `embedding` field |
|
||
|
||
---
|
||
|
||
## 13. Checklist triển khai
|
||
|
||
✅ Mapping ổn định
|
||
✅ ACL filter hoạt động
|
||
✅ Hybrid search default
|
||
✅ Highlight trả đúng trang
|
||
✅ Re‑index không cần SharePoint
|
||
|
||
---
|
||
|
||
*Kết thúc Index & Search Playbook. File tiếp theo sẽ là RAG / Chat Layer.*
|