Get in touch
or send us a question?
CONTACT

Full text search Mongodb – Chỉ một bài viết không cần nhiều.

Full text search là gì?

Đầu tiên chúng ta thống nhất với nhau là hiểu khái niệm Full text search là gì? này trước rồi mới tới việc thực hành. Full text search đơn giản chỉ là một hình thức nâng cao việc tìm kiếm dữ liệu trong database mà thôi.

Một người bình thường họ có thể mất nhiều steps để tìm ra một chuỗi cần thiết thì dẫn đến việc lâu và chậm, dẫn đến chản nản…, nếu người đó biết được khái niệm và thực hành về Fulltext search thì việc đó trở nên đơn giản hơn bao giờ hết. Và bài viết này tôi sẽ hướng dẫn về điều đó với Mongodb.

Full text search Mongodb

Đương nhiên để hiểu về Full text search in mongodb thì trước tiên điều kiện tiên quyết là bạn đã cài đặt và sử dụng mongodb rồi. Nếu bạn chưa biết thì có thể theo những hướng dẫn trong blogs này đã viết or có thể vào trang chủ của mongodb

Ok, xem như xong chúng ta sẽ đi tới thực hành. Đầu tiên giả sử bạn đã xong xuôi mọi chuyện và bạn sẽ insert data vào trong DB:

> use test
switched to db test
> db.players.insertMany([
... {"name": "cr7", "description": "ghi ban bang hai chan va bang dau"},
... {"name": "m10", "description": "ghi ban chan trai va chan phai"},
... {"name": "Haaland", "description": "ghi ban chan trai"},
... {"name": "M3p", "description": "ghi ban chan phai"},
... {"name": "greenwood", "description": "ghi ban bang dau"}
... ])

Trên đó là tôi insert một số cầu thủ đang hot với 2 khai báo: {name: '', description: ''}. Tôi nói nhanh thôi, nên không đi sâu vào chi tiết.

> db.players.find()
{ "_id" : ObjectId("61e8def4cfc05da9225c6250"), "name" : "cr7", "description" : "ghi ban bang hai chan va bang dau" }
{ "_id" : ObjectId("61e8def4cfc05da9225c6251"), "name" : "m10", "description" : "ghi ban chan trai va chan phai" }
{ "_id" : ObjectId("61e8def4cfc05da9225c6252"), "name" : "Haaland", "description" : "ghi ban chan trai" }
{ "_id" : ObjectId("61e8def4cfc05da9225c6253"), "name" : "M3p", "description" : "ghi ban chan phai" }
{ "_id" : ObjectId("61e8def4cfc05da9225c6254"), "name" : "greenwood", "description" : "ghi ban bang dau" }
>

OK tìm kiếm xong, như vậy là insert thành công. Tiếp đến sử dụng Full text search bằng cách sử dụng $text. Trước tiên khai báo index, nếu không bạn sẽ bị text index required for $text query như thế này:

> db.players.find({ $text:{ $search: 'ghi ban'} })
Error: error: {
"ok" : 0,
"errmsg" : "text index required for $text query",
"code" : 27,
"codeName" : "IndexNotFound"
}
>

Chúng ta khai báo index như sau để sử dụng Full text search trong Mongodb. Code như sau:

> db.players.createIndex({ "name": "text", "description": "text" });
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}

OK, xem như xong về index mongodb. Chúng ta chạy lại câu lệnh trên thì sẽ tìm thấy những documents có chứa giá trị tìm kiếm là ghi bàn.

> db.players.find({ $text:{ $search: 'ghi ban'} })

{ "_id" : ObjectId("61e8def4cfc05da9225c6254"), "name" : "greenwood", "description" : "ghi ban bang dau" }
{ "_id" : ObjectId("61e8def4cfc05da9225c6253"), "name" : "M3p", "description" : "ghi ban chan phai" }
{ "_id" : ObjectId("61e8def4cfc05da9225c6252"), "name" : "Haaland", "description" : "ghi ban chan trai" }
{ "_id" : ObjectId("61e8def4cfc05da9225c6251"), "name" : "m10", "description" : "ghi ban chan trai va chan phai" }
{ "_id" : ObjectId("61e8def4cfc05da9225c6250"), "name" : "cr7", "description" : "ghi ban bang hai chan va bang dau" }

Giờ tìm kiếm chan va bang dau thì chũng ta cũng nhận được hết 4 documents.

> db.players.find({ $text:{ $search: 'chan va bang dau'} })

{ "_id" : ObjectId("61e8def4cfc05da9225c6250"), "name" : "cr7", "description" : "ghi ban bang hai chan va bang dau" }
{ "_id" : ObjectId("61e8def4cfc05da9225c6254"), "name" : "greenwood", "description" : "ghi ban bang dau" }
{ "_id" : ObjectId("61e8def4cfc05da9225c6251"), "name" : "m10", "description" : "ghi ban chan trai va chan phai" }
{ "_id" : ObjectId("61e8def4cfc05da9225c6253"), "name" : "M3p", "description" : "ghi ban chan phai" }
{ "_id" : ObjectId("61e8def4cfc05da9225c6252"), "name" : "Haaland", "description" : "ghi ban chan trai" }
>

Vì khi chúng ta tìm nó tìm kiếm toàn văn bản cho nên nhận lệnh khớp các từ có trong cụm từ tìm kiếm trên. chanvabangdau.

Giờ chúng ta muôn chỉ tìm kiếm đúng chính xác là chan va bang dau thôi thì chúng ta chỉ thấy cr7 là có thể. Làm như sau:

> db.players.find({ $text:{ $search: '\"chan va bang dau\"'} })
{ "_id" : ObjectId("61e8def4cfc05da9225c6250"), "name" : "cr7", "description" : "ghi ban bang hai chan va bang dau" }
>

Chú ý dấu / là nó phân biệt chúng ta tìm không phải là JSON cho nên nó tìm kiếm cụm từ một cách chính xác.

Tiếp theo chúng ta chỉ tìm những cầu thủ chi ghi bàn bằng đầu thôi. Tìm kiếm như sau

> db.players.find({ $text:{ $search: 'bang dau'} })
{ "_id" : ObjectId("61e8def4cfc05da9225c6250"), "name" : "cr7", "description" : "ghi ban bang hai chan va bang dau" }
{ "_id" : ObjectId("61e8def4cfc05da9225c6254"), "name" : "greenwood", "description" : "ghi ban bang dau" }
>

Chúng ta nhận thấy mục đích chúng ta bị sai bởi vì muốn tìm cầu thủ chỉ ghi bằng đầu thôi mà có một document ghi bằng chân nữa. Chúng ta sẽ thay lại như sau:

> db.players.find({ $text:{ $search: 'bang dau -chan'} })
{ "_id" : ObjectId("61e8def4cfc05da9225c6254"), "name" : "greenwood", "description" : "ghi ban bang dau" }
>

-chan chính là giá trị tìm kiếm mà chúng ta không muốn tìm kiếm. Rất hay khải không?

Ngoài ra có một tiện ích đó là khi chúng ta tìm kiếm thì chỉ muốn giá trị đúng nhất, như elasticsearch làm được. Lúc đó bạn sẽ sử dụng $meta.

> db.players.find({ $text:{ $search: 'chan phai dau'}}, {score: {$meta: 'textScore'}})
{ "_id" : ObjectId("61e8def4cfc05da9225c6251"), "name" : "m10", "description" : "ghi ban chan trai va chan phai", "score" : 1.5357142857142856 }
{ "_id" : ObjectId("61e8def4cfc05da9225c6254"), "name" : "greenwood", "description" : "ghi ban bang dau", "score" : 0.625 }
{ "_id" : ObjectId("61e8def4cfc05da9225c6252"), "name" : "Haaland", "description" : "ghi ban chan trai", "score" : 0.625 }
{ "_id" : ObjectId("61e8def4cfc05da9225c6253"), "name" : "M3p", "description" : "ghi ban chan phai", "score" : 1.25 }
{ "_id" : ObjectId("61e8def4cfc05da9225c6250"), "name" : "cr7", "description" : "ghi ban bang hai chan va bang dau", "score" : 1.125 }
>

{score: {$meta: 'textScore'}} sẽ có nhiệm vụ sắp xếp những cụm từ chính xác theo điểm số score. Các bạn có thể nhìn lại như trên, tôi đã làm. Để ý thì thấy thứ tự nhảy lung tung cho nên chúng ta cần sắp xếp lại. Thì dùng sort().

Nguồn: https://anonystick.com/blog-developer/full-text-search-mongodb-chi-mot-bai-viet-khong-can-nhieu-2022012063033379

Leave a Reply

Your email address will not be published. Required fields are marked *