Vấn đềBạn sẽ gặp lỗi này khi MongoDB cố gắng index một trường vượt quá giới hạn 1.024 byte của storage engine WiredTiger. Nó thường xuất hiện trong quá trình thực hiện lệnh createIndex() trên một collection hiện có. Lỗi cũng xảy ra khi bạn chèn một document vào collection đã có index cho một chuỗi dài, chẳng hạn như một URL 2.000 ký tự hoặc một chuỗi ảnh mã hóa base64.
Thông báo lỗi chính xác trông như thế này:
WiredTigerIndex::insert: key too large to index, failing 1024 { : "..." }
Trong các phiên bản cũ hơn MongoDB 4.2, giới hạn này là một rào cản cố định. Nếu một trường được index đạt tới 1.025 byte, thao tác ghi hoặc tạo index của bạn sẽ thất bại ngay lập tức.
Xác định các Document gây lỗiTrước khi có thể sửa schema, bạn cần tìm các document cụ thể đang vi phạm quy tắc. Sử dụng aggregation framework để tính toán độ dài byte của trường gặp vấn đề. Đây là một script để tìm bất kỳ trường nào vượt quá 1.000 byte:
db.your_collection.aggregate([
{ $project: { field_length: { $strLenBytes: "$yourField" }, yourField: 1 } },
{ $match: { field_length: { $gt: 1000 } } },
{ $sort: { field_length: -1 } }
])
Đừng nhầm lẫn giữa byte và ký tự. Trong khi một chữ 'A' tiêu chuẩn là 1 byte, một emoji duy nhất như 🚀 chiếm tới 4 byte. Điều này có nghĩa là một chuỗi chỉ gồm 256 emoji sẽ kích hoạt lỗi 1.024 byte.
Giải pháp### 1. Sử dụng Hashed IndexHashed index là lựa chọn tốt nhất nếu bạn chỉ cần so khớp bằng (equality matches)—như tìm kiếm một URL dài cụ thể. Thay vì index chính chuỗi khổng lồ đó, MongoDB sẽ index một giá trị hash có kích thước cố định. Điều này bỏ qua hoàn toàn giới hạn 1.024 byte.
// Xóa B-tree index đang bị lỗi trước
db.your_collection.dropIndex("yourField_1")
// Tạo một hashed index thay thế
db.your_collection.createIndex({ yourField: "hashed" })
2. Sử dụng Text IndexChuyển sang text index nếu bạn cần tìm kiếm từ khóa bên trong chuỗi thay vì khớp chính xác toàn bộ giá trị. Text index chia nhỏ chuỗi thành các token riêng lẻ. Vì mỗi token thường nhỏ, bạn sẽ không gặp giới hạn 1.024 byte cho toàn bộ trường.
db.your_collection.createIndex({ yourField: "text" })
3. Cách xử lý tạm thời cho phiên bản cũ (MongoDB 4.0 trở xuống)Nếu bạn không thể thay đổi loại index ngay lập tức, bạn có thể yêu cầu MongoDB bỏ qua việc index các document quá lớn. Điều này ngăn cơ sở dữ liệu báo lỗi, nhưng có một lưu ý: những document đó sẽ không xuất hiện trong các truy vấn sử dụng index đó.
db.getSiblingDB("admin").runCommand({
setParameter: 1,
failIndexKeyTooLong: false
})
Lưu ý rằng MongoDB 4.2 đã loại bỏ tham số này. Các phiên bản mới hơn xử lý các key lớn một cách mượt mà hơn theo mặc định, mặc dù chúng vẫn phải đối mặt với các vấn đề về hiệu năng.
4. Hash dữ liệu trong mã nguồn của bạnĐôi khi bạn cần so khớp chính xác nhưng vẫn muốn dùng B-tree index tiêu chuẩn để đảm bảo hiệu năng. Trong trường hợp này, hãy hash trường đó trong logic ứng dụng (ví dụ dùng SHA-256) trước khi lưu. Lưu chuỗi hash 64 ký tự này vào một trường riêng biệt và index trường đó.
// Ví dụ Node.js
const crypto = require('crypto');
const longValue = "...chuỗi rất dài...";
const hashedValue = crypto.createHash('sha256').update(longValue).digest('hex');
db.collection.insertOne({
original_field: longValue,
field_hash: hashedValue
});
// Index chuỗi hash có độ dài cố định và nhỏ
db.collection.createIndex({ field_hash: 1 });
Xác minhSau khi áp dụng bản sửa lỗi, hãy xác minh xem index có thực sự được sử dụng hay không. Chạy explain() trên truy vấn thông thường của bạn để xem kế hoạch thực thi:
db.your_collection.find({ yourField: "some_value" }).explain("executionStats")
Hãy nhìn vào winningPlan. Nếu bạn đã sử dụng hashed index, stage phải là IXSCAN. Kiểm tra kỹ nReturned để đảm bảo các truy vấn của bạn đang tìm thấy các document như mong đợi.

