Full-text search with RediSearch Nodejs

Nội dung bài viết

RediSearch là một công cụ full-text search, có nghĩa là bạn có thể sử dụng thay cho elasticsearch nếu muốn, bài viết này giúp bạn hiểu sâu hơn về cách thực hiện tìm kiếm trong database và những ưu điểm khi sử dụng redisearch.

RediSearch là gì?

RediSearch là một công cụ full-text search, là một trong những module của redis. Về việc cài đặt thì bạn có thể xem qua bài trước, bài này sẽ giúp bạn cách thực hiện cần thiết để tìm kiếm dữ liệu một cách chính xác và nhanh chóng nhất.

Đương nhiên, để nhanh chóng hiểu nhanh và sâu điều kiện tiên quyết bạn phải hiểu về Redis. Và cách install redisearch, và một chút kiến thức về nodejs, và es6, ở đây có 138 bài viết về học ES6 - ES12.

Bài viết số 17 thuộc series - Con đường trở thành kiến trúc sư

Full Text Search là gì?

Tiếp theo bạn sẽ hiểu thêm về một khái niệm mà bạn đã nghe qúa nhiều rồi, và tôi xin phép được nói lại thêm chút nữa về khái niệm này. Đơn giản thôi, tìm kiếm văn bản làm sao cho khớp với cơ sở dữ liệu khi bạn lưu xuống, càng khớp đã tốt rồi, nhưng gợi ý thêm nữa thì tốt hơn nữa. Nếu như bạn đã sử dụng MySQL rồi thì có thể quen thuộc với truy vấn thông qua LIKE với ký tự %% được hỗ trợ bởi các cơ sở dữ liệu như PostgreSQL, MySQL. Ví dụ, khi bạn tìm kiếm %soc% thì nó tìm thấy khớp với socola, soccon.

Còn khi sử dụng RediSearch, ElasticSearch, để tìm kiếm Full Text Search thì có thể bạn tìm gone có thể sẽ khớp với going. Hiệu suất rất nhanh so với LIKE.

Use RediSearch

Sau đây bạn sẽ đi vào trọng tâm của bài viết này, đó là thực hành tìm kiếm với RediSearch. Lưu ý install redisearch thì bạn có thể xem lại ở bài trước. hoặc bạn có thể sử dụng DOCKER để install RediSearch.

$ docker run -p 6379:6379 redislabs/redisearch:latest

Bài này bạn sẽ biết được cách sử dụng redis-CLI để thực hiện với redisearch. Đầu tiên như MySQL hay Oracle thì chúng ta thử tạo index trong redisearch.

index

Để tạo được index thì bạn sử dụng command FT.CREATE như sau:

ft.create idx-products ON HASH PREFIX 1 product: SCHEMA title text sortable description text sortable quantity numeric sortable
OK

Add Documents

Khi tạo xong index rồi thì bạn có thể add dữ liêu thông qua hmset của redis.

hmset product:1 title "qua tao" description "nuoc trai cay tao" quantity 10
hmset product:2 title "qua xoai" description "nuoc trai cay xoai" quantity 15
hmset product:3 title "qua buoi" description "nuoc ep buoi" quantity 13

Chú ý: Tất cả các dữ liệu hash này được thêm vào tiền tố product:, và HMSET là của redis để tạo dữ liệu hash không liên quan đến redisearch này.

Để tìm kiếm bạn sử dụng FT.SEARCH, tìm kiếm này không phân biệt HOA hay THƯỜNG. Sau đây là hai ví dụ cụ thể

Tìm kiếm theo tiền tố

$ ft.search idx-products qu*
1) (integer) 3
2) "product:3"
3) 1) "title"
   2) "qua buoi"
   3) "description"
   4) "nuoc ep buoi"
   5) "quantity"
   6) "13"
4) "product:1"
5) 1) "title"
   2) "qua tao"
   3) "description"
   4) "nuoc trai cay tao"
   5) "quantity"
   6) "10"
6) "product:2"
7) 1) "title"
   2) "qua xoai"
   3) "description"
   4) "nuoc trai cay xoai"
   5) "quantity"
   6) "15"

Ví dụ trên đó bạn tìm qu* thì redisearch hiểu rằng tìm tiền tố và sẽ hiện thị những kêt quả liên quan như qua, quan...

Nếu bạn muốn chỉ lấy mỗi title thôi thì có thể làm như sau:

$ ft.search idx-products nu* return 1 title
1) (integer) 3
2) "product:3"
3) 1) "title"
   2) "qua buoi"
4) "product:1"
5) 1) "title"
   2) "qua tao"
6) "product:2"
7) 1) "title"
   2) "qua xoai"

Offet limit redisearch

ft.search idx-products nu* limit 0 10 return 1 title
1) (integer) 3
2) "product:3"
3) 1) "title"
   2) "qua buoi"
4) "product:1"
5) 1) "title"
   2) "qua tao"
6) "product:2"
7) 1) "title"
   2) "qua xoai"

Suggestion text Redisearch

Một trong những tính năng hay của Redisearch đó chính là tìm kiếm theo kiểu gợi. Nếu bạn sử dụng Shopee thì bạn có thể thấy tìm kiếm Shopee làm rất tốt ví dụ: full text search


Và ở đây bạn cũng làm được điều đó, đơn giản thôi.

$ ft.sugadd acc "qua xoai" 1
(integer) 1
$ ft.sugadd acc "qua xoai kho" 1
(integer) 2
$ ft.sugadd acc "qua coc" 1
(integer) 3
$ ft.sugadd acc "qua buoi" 1
(integer) 4
$ ft.sugget acc "qua"
1) "qua coc"
2) "qua buoi"
3) "qua xoai"
4) "qua xoai kho"
$ ft.sugget acc "qua x"
1) "qua xoai"
2) "qua xoai kho"
$ ft.sugget acc qu*
(empty array)
$ ft.sugget acc "qua xo"
1) "qua xoai"
2) "qua xoai kho"

Tìm kiếm coordinate sử dụng redisearch

Ở bài trước bạn đã thấy cách chúng tôi triển khai mã giảm giá cho hệ thống mà chỉ mỗi người một mã, không thể gian lận được. Và sau đó triển khai thêm phiếu giảm giá xung quanh vị trí người dùng, ở bài viết trước đó bạn sẽ tìm hiểu cách chuyển đổi một địa chỉ sang kinh độ và vĩ độ. Và bài viết này sẽ dùng chính toạ độ đó để filter các user hợp lệ xung quang 1 km hay bao nhiêu tuỳ bạn. Sau đây là cách sử dụng với redisearch.

$ FT.CREATE address SCHEMA location GEO
$ HGETALL 57956 location "-3.9264,57.5243" #[lON, LAT]
$ FT.SEARCH chinese restaurant @location:[-122.41 37.77 5 km]

Nên sử dụng RediSearch thay vì Elasticsearch?

Đương nhiên bạn không khẳng định được điều đó khi tuổi đời của RediSearch là rất ít, thậm chí khi tôi làm việc với RediSearch thì cũng phải tự buil một thư viện chuẩn nodejs với RediSearch để cho team làm việc. Vì mức độ tiếp cận của RediSearch trong cộng đồng đang rất ít.

Lợi thế của RediSearch chính là có một số điểm tối ưu hơn Elasticsearch. Ngoài ra nếu bạn đang sử dụng redis để làm cache cho hệ thống của bạn thì kết hợp RediSearch thì quá hoàn hảo.

Thôi, vậy thôi, bài tiếp theo tôi sẽ tiếp tục giới thiệu các viết thư viện nodejs và redisearch.

Có thể bạn đã bị missing