Tôi đang cố gắng sử dụng MongoDB để triển khai từ điển ngôn ngữ tự nhiên. Tôi có một bộ sưu tập các từ ngữ, mỗi từ có một số dạng từ như là các phần phụ. Đây là những gì một lexeme đơn trông giống như:Tăng tốc tìm kiếm chuỗi regex trong MongoDB
{
"_id" : ObjectId("51ecff7ee36f2317c9000000"),
"pos" : "N",
"lemma" : "skrun",
"gloss" : "screw",
"wordforms" : [
{
"number" : "sg",
"surface_form" : "skrun",
"phonetic" : "ˈskruːn",
"gender" : "m"
},
{
"number" : "pl",
"surface_form" : "skrejjen",
"phonetic" : "'skrɛjjɛn",
"pattern" : "CCCVCCVC"
}
],
"source" : "Mayer2013"
}
Hiện nay tôi có một bộ sưu tập của một số 4000 lexemes, và mỗi trong số này có trên trung bình một danh sách của một số 1000 wordforms (như trái ngược với chỉ 2 ở trên). Điều này có nghĩa là tôi có 4.000.000 biểu mẫu từ duy nhất trong bộ sưu tập một cách có ảnh hưởng và tôi cần có khả năng tìm kiếm chúng trong một khoảng thời gian hợp lý.
Một truy vấn bình thường sẽ trông như thế này:
db.lexemes.find({"wordforms.surface_form":"skrejjen"})
Tôi có một chỉ mục trên wordforms.surface_form
, và tìm kiếm này là rất nhanh. Tuy nhiên, nếu tôi muốn có các ký tự đại diện trong tìm kiếm của mình, hiệu suất sẽ không giống nhau. Ví dụ:
db.lexemes.find({"wordforms.surface_form":/skrej/})
mất hơn 5 phút (tại thời điểm này tôi đã bỏ cuộc chờ). Như đã đề cập in this question, tìm kiếm regex trên các chỉ mục được biết là xấu. Tôi biết rằng việc thêm^anchor vào các tìm kiếm regex helps a lot, nhưng nó cũng giới hạn nghiêm trọng khả năng tìm kiếm của tôi. Ngay cả khi tôi sẵn sàng hy sinh, tôi nhận thấy thời gian phản ứng vẫn có thể thay đổi rất nhiều tùy thuộc vào regex. Truy vấn
db.lexemes.find({"wordforms.surface_form":/^s/})
Mất 35 giây để hoàn tất.
Kết quả tốt nhất mà tôi đã có cho đến nay trên thực tế là khi tôi tắt chỉ mục bằng cách sử dụng hint
. Trong trường hợp này, mọi thứ dường như được cải thiện đáng kể. Truy vấn này:
db.lexemes.find({"wordforms.surface_form":/skrej/}).hint('_id_')
mất khoảng 3 giây để hoàn thành.
Câu hỏi của tôi là tôi có thể làm gì khác để cải thiện các thời gian tìm kiếm này không? Như họ đang có, họ vẫn còn một chút chậm và tôi đã xem xét việc chuyển sang MySQL với hy vọng nhận được hiệu suất. Nhưng tôi thực sự muốn giữ tính linh hoạt của Mongo và tránh tất cả sự bình thường tẻ nhạt trong một RDBMS. Bất kỳ đề xuất? Bạn có nghĩ rằng tôi sẽ chạy vào một số chậm đi bất kể động cơ DB, với số lượng dữ liệu văn bản này?
Tôi biết về tính năng mới text search của Mongo nhưng lợi thế của việc này (tokenisation và bắt nguồn) không liên quan trong trường hợp của tôi (chưa kể ngôn ngữ của tôi không được hỗ trợ). Nó không phải là rõ ràng nếu tìm kiếm văn bản thực sự là nhanh hơn hơn bằng cách sử dụng regex anyway.
Cảm ơn bạn đã đề xuất! Điều này tất nhiên giới thiệu rất nhiều thông tin dư thừa và sẽ làm cho bộ sưu tập tổng thể lớn hơn, tuy nhiên nếu nó làm tăng thời gian phản hồi tìm kiếm thì tôi có thể xem xét nó. Tôi sẽ chạy một vài thử nghiệm để xem đây có phải là trường hợp không và đăng cập nhật tại đây. –