1. Giới thiệu
Meilisearch là một search engine mã nguồn mở, tốc độ cao, tập trung vào trải nghiệm developer. Được viết bằng Rust, thiết kế theo hướng search-as-you-type (tìm kiếm ngay khi gõ).
2. Điểm nổi bật:
| Tính năng | Mô tả |
|---|---|
| Siêu nhanh | Phản hồi dưới 50ms ngay cả khi xử lý lượng dữ liệu lớn |
| Typo Tolerance | Tự động xử lý lỗi chính tả và từ khóa gần đúng |
| Full-text Search | Hỗ trợ tìm kiếm toàn văn bản với độ chính xác cao |
| Faceted Search | Hỗ trợ lọc dữ liệu theo danh mục, thuộc tính (facet) |
| RESTful API | Dễ dàng tích hợp thông qua giao tiếp HTTP API |
| Self-hosted | Triển khai trên server riêng, không phụ thuộc dịch vụ bên thứ ba |
| Multi-language | Hỗ trợ đa ngôn ngữ, bao gồm cả tiếng Việt |
3. Header bắt buộc
Content-Type: application/json
Authorization: Bearer <token>
4. Các loại Search
4.1. Single Index Search — Tìm kiếm trong một index
Tìm kiếm thông thường trong một index cụ thể.
POST /indexes/{indexUid}/search
4.2. Multi-Search — Tìm kiếm nhiều index cùng lúc
Cho phép gửi nhiều query trong một request duy nhất, giảm số lần gọi API.
POST /multi-search
JSON
{
"queries": [
{ "indexUid": "movies", "q": "action" },
{ "indexUid": "books", "q": "thriller" }
]
}
4.3. Federated Search — Tìm kiếm liên hợp
Tìm kiếm trên nhiều index và gộp kết quả thành một danh sách duy nhất, có ranking đồng nhất.
POST /multi-search
JSON
{
"federation": {},
"queries": [
{ "indexUid": "movies", "q": "batman" },
{ "indexUid": "comics", "q": "batman" }
]
}
4.4. Search with Filters — Tìm kiếm kết hợp lọc
Dùng thuộc tính filter để thu hẹp kết quả tìm kiếm theo điều kiện.
4.5. Faceted Search — Tìm kiếm phân loại
Dùng facets để lấy thống kê số lượng theo từng nhóm giá trị (ví dụ: bao nhiêu phim thuộc thể loại "Action").
4.6. Search with Geo (Geosearch) — Tìm kiếm theo vị trí địa lý
Tìm kiếm và sort theo tọa độ GPS.
JSON
{
"q": "restaurant",
"sort": ["_geoPoint(48.8566, 2.3522):asc"]
}
5. Các tham số trong Search API
Endpoint: GET\POST /indexes/{indexUid}/search
5.1. Tham số truy vấn cơ bản
| Tham số | Kiểu | Default | Mô tả |
|---|---|---|---|
q |
string |
— | Chuỗi tìm kiếm. Để trống → placeholder search (trả về tất cả documents). Dùng "..." cho phrase search. Dùng -word để loại trừ từ khóa. Chỉ xét tối đa 10 từ đầu tiên |
limit |
integer |
20 |
Số kết quả tối đa trả về. Không được vượt quá maxTotalHits. Bị bỏ qua khi sử dụng page / hitsPerPage
|
offset |
integer |
0 |
Bỏ qua N kết quả đầu tiên (phân trang thủ công). Bị bỏ qua khi sử dụng page / hitsPerPage
|
page |
integer |
— | Số trang hiện tại (bắt đầu từ 1). Dùng kèm với hitsPerPage. Khi thiết lập → response trả về totalHits và totalPages thay vì estimatedTotalHits
|
hitsPerPage |
integer |
20 |
Số kết quả trên mỗi trang. Đặt 0 để chỉ lấy totalHits chính xác mà không trả về documents |
5.2. Tham số lọc & sắp xếp
| Tham số | Kiểu | Default | Mô tả |
|---|---|---|---|
filter |
string |
— | Biểu thức lọc kết quả. Tất cả attributes dùng trong filter bắt buộc phải có trong filterableAttributes. Hỗ trợ geo filter: _geoRadius(), _geoBoundingBox(), _geoPolygon()
|
sort |
string[] |
— | Sắp xếp kết quả. Format: ["attribute:asc", "attribute:desc"]. Attribute phải có trong sortableAttributes. Hỗ trợ geo sort: _geoPoint(lat,lng):asc
|
facets |
string[] |
— | Trả về số lượng match theo từng giá trị facet. Dùng ["*"] để lấy tất cả filterableAttributes. Response sẽ có thêm facetDistribution và facetStats
|
distinct |
string |
— | Chỉ trả về 1 document đại diện cho mỗi giá trị unique của field này. Attribute phải có trong filterableAttributes. Override distinctAttribute của index |
matchingStrategy |
enum |
last |
Chiến lược match khi thiếu kết quả: last (bỏ bớt từ từ cuối), all (chỉ lấy kết quả khớp hoàn toàn), frequency (bỏ bớt từ phổ biến nhất trước) |
attributesToSearchOn |
string[] |
— | Giới hạn tìm kiếm chỉ trong các attributes được liệt kê. Mỗi attribute phải tồn tại trong searchableAttributes. Thứ tự không ảnh hưởng đến relevancy |
rankingScoreThreshold |
float |
— | Loại bỏ các kết quả có điểm ranking thấp hơn ngưỡng này (0.0 – 1.0). Các hits bị loại sẽ không được tính vào estimatedTotalHits, totalHits, hoặc facet |
locales |
enum[] |
— | Chỉ định ngôn ngữ của query theo chuẩn ISO-639. Override auto-detection. Ví dụ: ["vi", "en"]
|
Ví dụ filter nâng cao:
{
"filter": "genre = 'Action' AND rating > 7 AND NOT country = 'US'",
"sort": ["release_date:desc"]
}
5.3. Tham số hiển thị kết quả
| Tham số | Kiểu | Default | Mô tả |
|---|---|---|---|
attributesToRetrieve |
string[] |
["*"] |
Danh sách fields trả về trong mỗi document. Dùng ["*"] để lấy tất cả. Attributes không có trong displayedAttributes sẽ bị bỏ qua |
attributesToHighlight |
string[] |
— | Bôi đậm từ khóa match trong các attributes chỉ định. Kết quả xuất hiện trong _formatted. Dùng ["*"] để highlight tất cả fields trong attributesToRetrieve. Hỗ trợ cả synonyms và stop words |
highlightPreTag |
string |
"<em>" |
Chuỗi chèn trước từ được highlight. Có thể là HTML tag hoặc ký tự bất kỳ |
highlightPostTag |
string |
"</em>" |
Chuỗi chèn sau từ được highlight. Dùng cùng với highlightPreTag để tránh tạo HTML không hợp lệ |
attributesToCrop |
string[] |
— | Cắt ngắn nội dung và trả về đoạn trích (snippet) trong _formatted. Hỗ trợ syntax attribute:length để override theo từng attribute. Đoạn cắt được căn giữa quanh từ khóa match |
cropLength |
integer |
10 |
Số từ tối đa trong đoạn trích. Cả query terms và stop words đều được tính vào độ dài này |
cropMarker |
string |
"…" |
Ký hiệu đánh dấu vị trí bị cắt. Đặt null hoặc chuỗi rỗng nếu không muốn hiển thị marker. Chỉ xuất hiện khi có nội dung thực sự bị cắt |
showMatchesPosition |
boolean |
false |
Khi đặt true, mỗi hit sẽ có thêm _matchesPosition chứa byte offset (start + length) của từng term match. Hữu ích cho custom highlighting. Đơn vị là bytes, không phải characters
|
5.4. Tham số nâng cao
| Tham số | Kiểu | Default | Mô tả |
|---|---|---|---|
showRankingScore |
boolean |
false |
Khi đặt true, mỗi document sẽ có thêm field _rankingScore (0.0 – 1.0). Điểm càng cao → mức độ liên quan càng lớn. Rule sort không ảnh hưởng đến giá trị này |
showRankingScoreDetails |
boolean |
false |
Khi đặt true, mỗi document sẽ có thêm _rankingScoreDetails — breakdown điểm theo từng ranking rule. Hữu ích để debug relevancy |
showPerformanceDetails |
boolean |
false |
Khi đặt true, response sẽ có thêm object performanceDetails chứa timing breakdown của từng bước xử lý query |
Ví dụ request đầy đủ:
{
"q": "avengers",
"limit": 10,
"offset": 0,
"filter": "genre = 'Action' AND rating >= 7",
"sort": ["release_date:desc"],
"facets": ["genre", "director"],
"attributesToRetrieve": ["title", "poster", "rating", "genre"],
"attributesToHighlight": ["title", "description"],
"highlightPreTag": "<mark>",
"highlightPostTag": "</mark>",
"attributesToCrop": ["description"],
"cropLength": 20,
"showRankingScore": true,
"matchingStrategy": "all"
}
6. Cấu hình Settings (Index Settings)
Endpoint: GET/PATCH/DELETE /indexes/{indexUid}/settings
6.1. Searchable Attributes
Xác định trường nào được đưa vào full-text search index. Thứ tự trong array = mức độ ưu tiên (trường đầu tiên được ưu tiên cao nhất).
PUT /indexes/{indexUid}/settings/searchable-attributes
["title", "description", "tags"]
6.2. Displayed Attributes: Các trường được trả về trong kết quả search.
PUT /indexes/{indexUid}/settings/displayed-attributes
["title", "poster_url", "rating", "genre"]
6.3. Filterable Attributes: Khai báo các trường có thể dùng trong filter và facets. Bắt buộc phải khai báo trước khi dùng filter.
PUT /indexes/{indexUid}/settings/filterable-attributes
JSON
["genre", "rating", "country", "release_year"]
6.4. Sortable Attributes: Khai báo các trường có thể dùng để sort. Bắt buộc phải khai báo trước khi dùng sort.
PUT /indexes/{indexUid}/settings/sortable-attributes
JSON
["rating", "release_date", "price"]
6.5. Typo Tolerance: Kiểm soát mức độ chấp nhận lỗi chính tả.
PATCH /indexes/{indexUid}/settings/typo-tolerance
JSON
{
"enabled": true,
"minWordSizeForTypos": {
"oneTypo": 5,
"twoTypos": 9
},
"disableOnWords": ["iphone", "batman"],
"disableOnAttributes": ["serial_number"]
}
6.6. Synonyms: Cấu hình từ đồng nghĩa để mở rộng khả năng tìm kiếm.
PUT /indexes/{indexUid}/settings/synonyms
JSON
{
"phone": ["smartphone", "mobile", "điện thoại"],
"car": ["automobile", "vehicle", "xe hơi"],
"ai": ["artificial intelligence", "machine learning"]
}
6.7. Stop Words: Loại bỏ các từ không có giá trị tìm kiếm khỏi query.
PUT /indexes/{indexUid}/settings/stop-words
JSON
["the", "a", "an", "is", "are", "và", "của", "cho"]
6.8. Distinct Attribute: Chỉ lấy 1 kết quả đại diện cho mỗi giá trị unique.
PUT /indexes/{indexUid}/settings/distinct-attribute
JSON
"product_id"
6.9. Faceting: Cấu hình tính năng faceted search.
PATCH /indexes/{indexUid}/settings/faceting
JSON
{
"maxValuesPerFacet": 100,
"sortFacetValuesBy": {
"*": "alpha",
"rating": "count"
}
}
6.10. Pagination: Cấu hình giới hạn phân trang.
PATCH /indexes/{indexUid}/settings/pagination
JSON
{
"maxTotalHits": 1000
}
6.11. Embedders (Semantic Search): Cấu hình vector embedding cho AI/semantic search.
PATCH /indexes/{indexUid}/settings/embedders
JSON
{
"myEmbedder": {
"source": "openAi",
"apiKey": "sk-...",
"model": "text-embedding-3-small",
"documentTemplate": "{{doc.title}} {{doc.description}}"
}
}
7. Ranking Rules
Ranking Rules xác định thứ tự ưu tiên khi tính điểm liên quan của kết quả. Rule đứng trước có độ ưu tiên cao hơn.
Endpoint: GET/PUT /indexes/{indexUid}/settings/ranking-rules
| Rule | Mô tả |
|---|---|
words |
Ưu tiên document chứa nhiều từ trong query hơn |
typo |
Ưu tiên document có ít lỗi chính tả hơn |
proximity |
Ưu tiên document có các từ xuất hiện gần nhau hơn trong nội dung |
attribute |
Ưu tiên match ở field có độ ưu tiên cao hơn (theo thứ tự trong searchableAttributes) |
sort |
Áp dụng tiêu chí sắp xếp do người dùng truyền vào |
exactness |
Ưu tiên document khớp chính xác với từ khóa hơn |
Mặc định:
["words", "typo", "proximity", "attribute", "sort", "exactness"]
Custom ranking rules: Có thể thêm rule tùy chỉnh theo trường cụ thể:
["words", "typo", "proximity", "attribute", "sort", "exactness", "rating:desc", "release_date:asc"]
_
Tips: Đặt sort lên trước nếu muốn ưu tiên tiêu chí sắp xếp của người dùng hơn là độ liên quan ngữ nghĩa. Đặt exactness lên trước nếu cần match chính xác cao._
8. Các API xóa dữ liệu
8.1. Xóa toàn bộ Index
DELETE /indexes/{indexUid} : Xóa cả cấu hình lẫn dữ liệu của index.
8.2. Xóa tất cả Documents trong Index
DELETE /indexes/{indexUid}/documents
8.3. Xóa Document theo ID
DELETE /indexes/{indexUid}/documents/{documentId}
8.4. Xóa nhiều Documents theo danh sách ID
POST /indexes/{indexUid}/documents/delete-batch
[1, 2, 3, 42, 100]
8.5. Xóa Documents theo Filter
POST /indexes/{indexUid}/documents/delete
{
"filter": "genre = 'Horror' AND release_year < 2000"
}
8.6. Reset Settings về mặc định
DELETE /indexes/{indexUid}/settings: Reset từng phần setting cụ thể:
DELETE /indexes/{indexUid}/settings/synonyms
DELETE /indexes/{indexUid}/settings/stop-words
DELETE /indexes/{indexUid}/settings/ranking-rules
DELETE /indexes/{indexUid}/settings/filterable-attributes
DELETE /indexes/{indexUid}/settings/sortable-attributes
DELETE /indexes/{indexUid}/settings/searchable-attributes
DELETE /indexes/{indexUid}/settings/typo-tolerance
DELETE /indexes/{indexUid}/settings/faceting
DELETE /indexes/{indexUid}/settings/pagination
DELETE /indexes/{indexUid}/settings/embedders
8.7. Hủy Task đang chờ xử lý
Cho phép hủy các task chưa hoàn thành (enqueued, processing) theo nhiều điều kiện khác nhau.
POST /tasks/cancel?uids=1,2,3
POST /tasks/cancel?indexUids=movies
POST /tasks/cancel?statuses=enqueued,processing
| Tham số | Kiểu | Mô tả |
|---|---|---|
uids |
string |
Danh sách task UID cần hủy, phân tách bằng dấu phẩy |
indexUids |
string |
Hủy tất cả task thuộc các index được chỉ định |
statuses |
string |
Hủy task theo trạng thái (enqueued, processing) |
Response
{
"taskUid": 42,
"indexUid": null,
"status": "enqueued",
"type": "taskCancelation",
"enqueuedAt": "2026-05-21T10:00:00Z"
}
8.8. Xóa lịch sử Task
Cho phép xóa lịch sử task đã hoàn thành hoặc thất bại khỏi hệ thống.
DELETE /tasks?uids=1,2,3
DELETE /tasks?indexUids=movies
DELETE /tasks?statuses=succeeded,failed
Query Parameters
| Tham số | Kiểu | Mô tả |
|---|---|---|
uids |
string |
Danh sách task UID cần xóa |
indexUids |
string |
Xóa tất cả task thuộc các index được chỉ định |
statuses |
string |
Xóa task theo trạng thái (succeeded, failed) |
Response trả về thông tin task deletion đã được enqueue:
{
"taskUid": 43,
"indexUid": null,
"status": "enqueued",
"type": "taskDeletion",
"enqueuedAt": "2026-05-21T10:05:00Z"
}
Top comments (0)