Một lát cắt đặc tả mapping của index user

Một phần của tài liệu Xây dựng hệ quản trị đào tạo tích hợp mạng xã hội (Trang 129 - 132)

 Trường dữ liệu có thể tùy chọn khơng index (bằng cách tùy chọn index là false như ở hình trên). Mặc dù trường này vẫn được lưu trữ và trả ra trong kết quả tìm kiếm, ElasticSeach sẽ khơng tạo index ngược cho trường này. Việc này rất hữu ích để hệ thống thực hiện việc lưu trữ thêm các thông tin khác của thực thể vào index để không phải query vào cơ sở dữ liệu chính giảm hiệu năng, nhưng vẫn đảm bảo rằng việc index các thông tin này vào Elasticsearch vẫn nhanh chóng (vì khơng cần phải xây

index ngược).

 Mọi kiểu dữ liệu trong ElasticSearch đều có thể chứa một danh sách giá trị. Do đó, trong ES khơng hề có kiểu array.

 Có thể lưu trữ đối tượng lồng nhau (nested object). Hệ thống sử dụng kiểu dữ liệu này để lưu trữ danh sách thực thể có liên quan với thực thể chính. Vì trong ElasticSearch khơng hề có khái niệm Quan hệ, đây là giải pháp để hiện thực quan hệ 1 – N và quan hệ M – N. Ví dụ ở hình trên, hệ thống lưu trữ những người dùng là bạn của người dùng chính. Đây là mối quan hệ M – N, do đó cần phải tạo kiểu dữ liệu nested. Hệ thống chỉ sử dụng kiểu dữ liệu nested này cho mục đích lọc và sắp xếp dữ liệu. Cũng là ví dụ bạn bè trên, với mapping này chúng ta có thể hỗ trợ tìm kiếm lọc những người có tên phù hợp với từ khóa và có id của friends trùng với id của người dùng đang đăng nhập Mặc định các câu query trong ES đều có tốn tử là OR, nên chỉ cần một phần tử trong danh sách nested objects này trùng thì sẽ tính là match. Có thể thấy nhược điểm của cách làm này đó chính là đánh đổi về bộ nhớ. Giả sử ta có mối quan hệ M – N, thì ta chỉ mất ít nhất M + N + (M × N) bộ nhớ khi lưu ở SQL, trong khi đó đối với kiểu nested thì sẽ là M + N + 2(M × N) (giả sử ta lưu nested ở cả hai chiều). Ngồi ra, một

nhược điểm nữa đó là ở hiệu năng và độ phức tạp khi thêm, xóa, sửa quan hệ. Khi xóa bạn bè chẳng hạn, ta cần phải tìm trong danh sách đối tượng nested friends và xóa kết quả trùng id đi. Tác vụ này có độ phức tạp là O(N) so với O(1) trong trường hợp SQL. Ngoài kiểu dữ liệu, tại thời điểm tạo index, chúng ta cũng cần phải xác định thêm bộ

analyzer được sử dụng cho các trường dữ liệu đó. Analyzer được sử dụng để chuyển đổi văn

bản khơng có cấu trúc (tên người dùng, mơ tả khóa học) thành dạng có cấu trúc tối ưu cho việc tìm kiếm. Cấu trúc của một analyzer gồm ba phần:

1. char_filter: Bộ lọc ký tự tiền xử lý trước khi đưa vào tokenizer, ví dụ html_strip dùng

để loại bỏ các phần tử HTML khỏi đoạn văn.

2. tokenizer: chuyển đổi dạng ký tự thô nhận được thành các token để đánh index ngược.

Một số tokenizer phổ biến: standard chia văn bản thành từ dựa trên ký tự phân cách từ (ví dụ như khoảng trắng) và loại bỏ các dấu chấm câu – đây cũng là tokenizer mặc định cho trường dạng text; n-gram chia văn bản thành các từ và trả về chuỗi n ký tự liên tục của mỗi từ đó (ví dụ 2-gram của math sẽ là ma, at, th); keyword tokenizer trả về đúng văn bản nhận vào – đây là tokenizer mặc định cho trường dạng keyword.

3. filter: nhận vào danh sách các token và trả ra danh sách token mới được biến đổi theo

một cách nào đó. Một số filter tiêu biểu: lowercase dùng để chuyển thành chữ thường (quan trọng vì tìm kiếm thường phải khơng phân biệt chữ hoa và chữ thường); ascii- folding: chuyển đổi ký tự unicode thành dạng ASCII tương ứng (ví dụ ă thành a).

ElasticSearch cung cấp sẵn một analyzer chuẩn tắc (standard) bao gồm standard

tokenizer và lowercase filter. Analyzer đáp ứng gần như đầy đủ nhu cầu sử dụng. Tuy vậy,

trong quá trình, hệ thống phát sinh một số use-case mà nhóm làm đề tài cần phải mở rộng thêm từ analyzer này như sau:

 Tìm kiếm tiếng việt. Hiện tại, hệ thống hỗ trợ tìm kiếm tiếng việt thơng qua dạng ASCII tương ứng của nó. Ví dụ, cụm từ “tốn học” sẽ được quy thành “toan hoc” tại thời điểm đánh index và thời điểm truy vấn. Nhóm làm đề tài quyết định sử dụng filter

 Tìm kiếm các đoạn văn bản có nhập thẻ HTML. Đối với những trường dữ liệu như mơ tả khóa học,… hệ thống cho phép nhập văn bản dạng rich text, tức là có thể chứa các định dạng văn bản dưới dạng thẻ HTML. Nhóm làm đề tài quyết định sử dụng

char_filter html_strip để hiên thực tính năng này.

 Tìm kiếm từng phần (partial match). Đối với các đoạn văn bản ngắn như tên người dùng, tên nhóm và tên khóa học thì tìm kiếm full-text khơng thơi là rất hạn chế. Chúng ta cần hỗ trợ tìm kiếm từng phần (ví dụ như nhập Qua thì có thể ra được kết quả Qn chẳng hạn). Để hỗ trợ tính năng này, hệ thống sử dụng filter edge-ngram. Edge-ngram gần giống với n-gram, khác biệt nằm ở chỗ các n-gram phải chứa ký tự bắt đầu của từng token. Với văn bản “con mèo”, filter này sẽ sinh ra các 2-gram là co và me. Filter này cho phép định nghĩa min-gram và max-gram, tương ứng với số n ít nhất và nhiều nhất filter này có thể sinh ra các n-gram. Filter này cũng được nhóm làm đề tài sử dụng để hiện thực tính năng search-as-you-type giúp tăng trải nghiệm tìm kiếm của người dùng. Ở ví dụ của hình dưới, nhóm làm đề tài định nghĩa hai analyzer,

partial_analyzer dùng để đánh index trường dữ liệu cần tìm kiếm một phần và partial_search dùng để biến đổi kết quả tìm kiếm. Nhắc lại, mặc định văn bản sẽ được

biến đổi sử dụng cùng 1 loại analyzer khi đánh index và khi tìm kiếm. Ở đây nhóm làm đề tài định nghĩa hai loại riêng biệt sử dụng cho hai trường hợp vì khi tìm kiếm thì chúng ta khơng cần phải biến đổi kết quả này thành n-gram như khi index.

Một phần của tài liệu Xây dựng hệ quản trị đào tạo tích hợp mạng xã hội (Trang 129 - 132)