|
|
 |
| Tiêu Điểm |
|
 |
|
|
|
Tìm kiếm toàn văn trong MySQL
Thứ Bẩy, 02.06.2007, 02:31pm (GMT+7)
Khi
dữ liệu ngày càng nhiều thì vấn đề tìm kiếm thông tin chính xác càng
trở nên quan trọng. Với khối lượng dữ liệu lớn và có tổ chức phức tạp,
vấn đề đặt ra là làm thế nào để tìm nhanh và đúng thông tin cần. Người
dùng không muốn tìm kiếm một từ mà lại có cả triệu câu trả lời, họ cần
sự chính xác và loại bỏ các từ gây nhiễu. Lúc đó, người dùng sẽ cần đến
tính năng tìm kiếm toàn văn.
Tìm
kiếm toàn văn (TKTV) đã được hỗ trợ trong MySQL version 3.23.23. Các
cột VARCHAR và TEXT được đánh chỉ mục với FULLTEXT có thể dùng được với
các câu lệnh SQL đặc biệt để thực hiện việc tìm kiếm toàn văn trong
MySQL. Đến bản 4.1, tính năng này trở nên hoàn thiện với sự hỗ trợ đầy
đủ tìm kiếm boolean.
Tìm kiếm toàn văn trong MySQL
TKTV
là một chức năng có trong MySQL cho phép người dùng tìm kiếm các mẩu
thông tin khớp với một chuỗi trên một hay một số bảng nhất định, hơn là
tìm sự so khớp dạng "SELECT LIKE" trên từng hàng của một trường nào đó.
Một chỉ mục toàn văn trong MySQL là một chỉ mục có kiểu
FULLTEXT. Các chỉ mục FULLTEXT chỉ được dùng với các bảng MyISAM và có
thể được tạo ra từ các cột CHAR, VARCHAR, hay TEXT vào lúc tạo bảng với
CREATE TABLE hay bổ sung sau với ALTER TABLE hoặc CREATE INDEX.
Chỉ
mục TKTV rất giống với các chỉ mục khác: nó là một danh sách các khóa
được xếp theo trật tự. Các khóa này chỉ đến các bản ghi nằm trong file
dữ liệu. Mỗi khóa gồm (định dạng của phiên bản 4.1):
{
Word -- VARCHAR. Một từ bên trong phần văn bản.
Count -- LONG. Từ đó xuất hiện bao nhiều lần trong phần văn bản.
}
{
Weight -- FLOAT. Đánh giá về tầm quan trọng của từ.
Rowid -- một con trỏ chỉ đến hàng cụ thể nằm trong file dữ liệu.
}
Một số đặc điểm chính của tính năng TKTV trong MySQL:
• Tự loại bỏ các từ có ít hơn 4 chữ cái.
• Các từ có gạch ngang nằm giữa được xem là 2 từ.
• Các hàng được trả lại theo thứ tự thích hợp, từ cao xuống thấp
•
Các từ nằm trong danh sách từ phổ thông bằng tiếng Anh cũng bị loại bỏ
khỏi danh sách kết quả tìm kiếm. Danh sách từ này nằm trong file
myisam/ft_static.c. Khi bạn cần lọc các từ thông dụng cho một ngôn ngữ
khác, ví dụ tiếng Việt thì bạn cần chỉnh lại file này, biên dịch lại
MySQL, và xây dựng lại các chỉ mục!
Chuẩn bị dữ liệu
Chúng ta thử triển khai một ví dụ đơn giản để hình dung rõ hơn về cơ chế hoạt động của TKTV.
Đầu tiên, chúng ta tạo ra một CSDL tên goldenkey từ cửa sổ dòng lệnh (console) của MySQL:
Tiếp
theo, chúng ta tạo ra một bảng dùng mệnh đề FULLTEXT của MySQL để chỉ
định những trường mà chúng ta muốn đánh chỉ mục cho việc tìm kiếm: create table Staff
(
pk_id int auto_increment not null,
firstName varchar(20),
lastName varchar(20),
age int,
details text,
primary key(pk_id),
unique id(pk_id),
fulltext(firstName, lastName, details)
) ENGINE=MyISAM; Sau khi thực hiện câu lệnh này, bạn được một bảng có cấu trúc như sau:

trường
pk_id đầu tiên được dùng làm khóa chính. Chúng ta đã dùng mệnh đề
FULLTEXT để đánh chỉ mục cho nhóm 3 trường là firstName, lastName và
details.
Nếu đã lập bảng như trên và muốn thay đổi trường có chỉ mục, bạn dùng lệnh sau:
ALTER TABLE Staff ADD FULLTEXT(field1, field2);
Ở đây, bạn chú ý dòng fulltext(firstName, lastName, details).
Dòng này thông báo cho MySQL thiết lập một chỉ mục lên các trường
firstName, lastName và details của bảng Staff. Các chỉ mục chỉ có thể
được tạo ra trên các trường có kiểu là VARCHAR và TEXT. Khi các trường
này đã có chỉ mục thì CSDL đã sẵn sàng cho việc khai thác tính năng
TKTV để tìm các bản ghi phù hợp yêu cầu tìm kiếm dựa trên các giá trị
có trong ba trường này.
Để thử nghiệm, chúng ta bổ sung dữ liệu vào bảng mới tạo bằng các câu lệnh sau:
insert
into Staff values(0, Jeff, Holmes, 52, Mr. Jeff Holmes is a senior
teacher in Golden Key. He likes Business, Technology and Finance. He is
responsible for English for Information Technology course in Golden
Key.);
insert into Staff values(0, Beth, Adams, 29, Mrs. Beth
Adams is the Director of Studies of Golden Key Language Center. She was
born in England. She is very nice and professional.);
insert
into Staff values(0, Jason, Bell, 33, Mr. Jason Bell is a business
assistant in Golden Key. He graduated from London Business Management
School. His major is Law in Business.);
Chú ý là TKTV được thiết kế cho các bảng dữ liệu lớn, khi dữ liệu càng lớn thì kết quả trả về càng đáng tin cậy.
Thực hiện tìm kiếm
Sử dụng lệnh TKTV:
select firstName from Staff where match(firstName, lastName, details) against(business);
Kết quả trả lại như sau:

Chúng ta sẽ phân tích để thấy được sự khác biệt. Đầu tiên, xem xét phần SELECT và FROM trong câu truy vấn:
select firstName from Staff
Ở đây không có gì khác biệt so với các câu SELECT bình thường khác. Nhưng sự khác biệt nằm ở phần mệnh đề WHERE tiếp sau đó:
where match(firstName, lastName, details) against(business);
Đây
chính là chỗ phát huy sức mạnh của TKTV. Trong phần đầu của câu truy
vấn này, bạn dùng câu lệnh MATCH. Lệnh này sẽ tiến hành so khớp yêu cầu
tìm kiếm với các giá trị của các trường firstName, lastName và details.
Khi câu lệnh MATCH được sử dụng trong mệnh đề SELECT nó sẽ trả
lại một thứ tự sắp xếp theo mức độ thích hợp, được xác định bằng một
con số thập phân dương. Số này càng gần với 0 thì bản ghi càng kém
thích hợp. Giá trị thích hợp này được xác định dựa trên biểu thức tìm
kiếm, số từ có trong các trường được đánh chỉ mục cũng như tổng số bản
ghi được tìm kiếm.
Câu lệnh AGAINST chỉ chấp nhận một tham số. Đó là chuỗi mà chúng ta cần tìm.
Tuy nhiên, cho đến bây giờ chúng ta vẫn chưa thấy được sự khác biệt với cách tìm kiếm truyền thống dựa trên câu lệnh LIKE:
select firstName from Staff where details like business;
Bạn
hãy thực hiện câu lệnh trên để xem chúng có trả về cùng một tập kết quả
không? Câu trả lời có thể là: có và không. Chính sự can thiệp của thứ
tự sắp xếp theo mức độ thích hợp đã làm cho tập kết quả này có sự sai
khác với tập kết quả có từ TKTV.

Sắp xếp theo độ thích hợp
Để kiểm tra con số đánh giá mức độ thích hợp, chúng thực hiện câu lệnh truy vấn sau:
select
concat(firstName, , lastName) as name, match(firstName, lastName,
details) against(business) as relevance from Staff where
match(firstName, lastName, details) against(business);
Kết quả trả lại như sau:
Trong
câu truy vấn này, chúng ta sử dụng lệnh MATCH trong mệnh đề SELECT để
gửi trả lại chỉ số đánh giá mức độ thích hợp cho mỗi bản ghi. Câu lệnh
trên thực hiện việc TKTV trên các trường firstName, lastName và details
để so khớp chuỗi "business":
where match(firstName, lastName, details) against(business);
Câu
lệnh truy vấn này trả về hai bản ghi có chứa chuỗi "business" nằm ở một
trong các trường firstName, lastName hay details. Bây giờ chúng ta sẽ
xem lại các bản ghi có chứa chuỗi "business":
"Ms. Nguyen
Hoang Ly is the Marketing and Business Development Manager In Golden
Key Language Center. If you want to talk about business cooperation,
please call her."
"Mr. Jeff Holmes is a senior teacher in
Golden Key. He likes Business, Technology and Finance. He is
responsible for English for Information Technology course in Golden
Key."
"Mr. Jason Bell is a business assistant in Golden Key. He
graduated from London Business Management School. His major is Law in
Business."
Trường relevance trả lại từ câu truy vấn của chúng ta được tạo ra từ chuỗi lệnh sau:
match(firstName, lastName, details) against(business) as relevance
Bạn
có thể thấy chuỗi lệnh này đã được dùng đến hai lần: một lần trong mệnh
đề SELECT và một lần trong mệnh đề WHERE. MySQL chọn giải pháp này và
chỉ thực hiện một lần TKTV trên bảng chứ không phải hai lần. Điều đó có
nghĩa là sẽ không "tốn thêm sức" xử lý cho các câu truy vấn như thế
này. Rõ ràng đây là một lợi thế lớn giúp tiết kiệm tài nguyên và thời
gian so với các câu truy vấn đơn giản thực hiện trên một CSDL lớn.
Khi
câu lệnh MATCH được dùng trong mệnh đề WHERE, MySQL tự động xếp các
hàng từ mức thích hợp cao nhất đến mức thấp nhất. Đây là câu truy vấn
trả lại chỉ số xếp hạng thích hợp cho tất cả các bản ghi:
select concat(firstName, , lastName) as name, match(firstName, lastName, details) against(business) as relevance from Staff;
Chúng ta đã bỏ mệnh đề WHERE ra ngoài, do vậy các bản ghi trả lại không xếp theo thứ tự.

Ở
phần đầu, khi liệt kê các điểm mạnh của TKTV tôi có chỉ ra rằng MySQL
xóa bỏ các từ gây nhiễu và các từ có ít hơn 4 kí tự. Chúng ta sẽ kiểm
tra điểm mạnh này bằng hai câu truy vấn TKTV sau:
select firstName, match(firstName, lastName, details) against(he likes business) as relevance from Staff;
Kết quả của câu truy vấn này như sau:
Chú
ý, câu truy vấn cuối cùng của chúng ta có hai từ có độ dài hơn 3 kí tự
là, "business" và "likes". Nếu chúng ta xóa bỏ từ có dưới 3 kí tự kia
đi thì chúng ta sẽ có kết quả về chỉ số thích hợp tương tự như trên:
select firstName, match(firstName, lastName, details) against(likes business) as relevance from Staff;
Kết quả trả lại như sau:

Như
vậy, chúng ta vẫn có kết quả trả lại tương tự. Điều này chứng tỏ MySQL
đã xóa bỏ các từ gây nhiễu và các từ có từ 3 kí tự trở xuống ra khỏi
câu truy vấn.
Chức năng TKTV của MySQL xếp hạng các từ dựa
trên giá trị ngữ nghĩa của chúng – các từ thông dụng thì xếp hạng thấp
hơn các từ không thông dụng. Điều này có ý nghĩa, vì một từ tồn tại
trong nhiều bản ghi sẽ có tính thích hợp ít hơn so với một từ chỉ xuất
hiện trong một hay hai bản ghi. Việc xếp hạng thích hợp theo ý nghĩa
được sử dụng ở phần lớn các thuật toán TKTV phổ biến.
Giới hạn 50%
MySQL
loại bỏ các từ gây nhiễu và các từ ngắn nhưng nếu một từ không ngắn
nhưng hiện diện ở hơn 50% số bản ghi được tìm kiếm thì các bản ghi đó
sẽ không được trả lại. MySQL gọi đó là "50% threshold". Ở một mức độ
nào đó điều này có ý nghĩa vì nó lọc ra tất cả các bản ghi có chỉ số
thích hợp thấp.
Tìm kiếm toàn văn với toán tử boolean
Bằng
cách kết hợp nhiều toán tử bên trong chuỗi tìm kiếm, bạn có thể đưa vào
hay loại trừ các từ khác, thay đổi các tổ hợp từ để thay đổi giá trị
thích hợp... Sau đây là một số toán tử boolean thường dùng trong MySQL:
• + Dấu cộng ở đầu chỉ ra rằng từ này phải xuất hiện ở tất cả các hàng trả lại.
• - Dấu trừ ở đầu chỉ ra rằng từ này không được có mặt trong tất cả các hàng trả lại.
• Mặc định (khi không có dấu trừ hoặc dấu cộng) từ tìm kiếm là tùy chọn, nhưng hàng nào chứa từ đó sẽ được đánh giá cao hơn.
• < >
Hai toán tử này được sử dụng để thay đổi phần đóng góp của từ vào giá
trị thích hợp của một hàng. Toán tử < làm giảm, còn toán tử > làm
tăng phần đóng góp.
• ( ) Các dấu ngoặc đơn được sử dụng để nhóm các từ vào một biểu thức con.
• ~
Dấu ngã nằm ở đầu có chức năng toán tử phủ định, làm cho phần đóng góp
của từ vào giá trị thích hợp của hàng bị phủ định. Kí hiệu này có ích
khi dùng để đánh giá các từ gây nhiễu. Một hàng có chứa một từ như vậy
sẽ bị đánh giá thấp hơn các hàng khác, nhưng không có nghĩa là nó bị
loại trừ, như trường hợp dùng toán tử - .
• * Một dấu hoa thị là toán tử cắt bỏ. Không giống như các toán tử khác, nó được nối vào từ chứ không phải đặt nó ở trước từ.
• "Mệnh đề được đặt trong dấu nháy kép", sẽ chỉ so khớp với các hàng có chứa mệnh đề đó.
Một
tìm kiếm boolean được thực hiện khá giống với TKTV bình thường. Tuy
nhiên, nó chứa từ khóa IN BOOLEAN MODE, như ví dụ dưới đây:
select * from Staff where match(firstName, lastName, details) against (+business -English in boolean mode);
Trong
câu truy vấn trên, chúng ta đã ra lệnh rằng tất cả các hàng trả lại
phải chứa từ "business" và không được chứa từ "English". Tương tự,
chúng ta thử thực hiện câu truy vấn dưới đây:
select
firstName, match(firstName, lastName, details) against(+English
-business >manager in boolean mode) as relevance from Staff where
match(firstName, lastName, details) against(+ English - business >
manager in boolean mode);
Nhìn vào câu truy vấn ở trên ta thấy hàng trả lại sẽ được xếp ở vị trí cao hơn nếu:
• Nó chứa từ "English"
• Nó không chứa từ "business"
• Từ "manager" sẽ xuất hiện trong hàng đó một hay nhiều lần
Kết quả như sau:

Tất cả các bản ghi trả lại đều có giá trị xếp hạng thích hợp là 0 và do đó sẽ không có mặt trong kết quả trả về. Bạn có thể kiểm chứng kết quả này bằng việc thực thi:
select firstName from Staff where match(firstName, lastName, details) against(+English -business >manager in boolean mode);
Bạn sẽ thấy:
Kết luận
TKTV
cho phép bạn tìm kiếm một cách thông minh, nhanh và giảm thiểu nhu cầu
viết các câu truy vấn tìm kiếm phức tạp. Với TKTV, bạn sẽ tiết kiệm
được tài nguyên, thời gian xử lý và giúp tăng độ thích hợp trong kết
quả tìm kiếm với các CSDL có lượng nội dung lớn, đem lại sự hài lòng
cho người dùng. Tài liệu tham khảo: 1. Full text search in MySQL, http://dev.mysql.com/doc/mysql/en/fulltext-search.html 2. Golden Key Research Materials, http://www.goldenkey.edu.vn
Theo QuangTriMang
|
|
|
|