09/10/2018, 23:39

Tìm kiếm theo cụm từ

Kính nhờ các bác chỉ giáo cho tui 1 điểm chưa rõ về cách viết trang tìm kiếm insite.

Hiện tại, tui vẫn dùng cách cũ là phân tích chuỗi gửi lên bởi khách, và tách ra thành từng từ theo khoảng trắng rồi push vào 1 mảng. Mảng này có phần tử đầu tiên là chuỗi gốc. Ví dụ khách nhập vào cụm từ "Giải thuật tìm kiếm", không có dấu ngoặc kép, thì 1 mảng $Keyword gồm 5 phần tử : "Giải thuật tìm kiếm", "Giải", "thuật", "tìm", "kiếm"; sẽ được tạo ra. Sau đó câu lệnh SQL sẽ có dạng :

"Select * From tblTablename WHERE FieldName like '%".$Keyword[0]."%'
OR FieldName like '%".$Keyword[1]."%' ....

Câu lệnh trên có vẻ khá hợp lý, và kết quả trả về là chính xác nếu từ khóa chỉ gồm 1 từ ! Còn khi từ khóa là một chuỗi thì kết quả lại nằm trên 1 phạm vi khá rộng. Ví dụ gõ "a và b", không có dấu nháy kép, thì nó trả về toàn bộ các bài viết, vì bài nào mà chẳng chứa ký tự "a"

Bây giờ tui mô phỏng Google, ưu tiên tìm kiếm riêng các cụm từ nằm trong ngoặc kép. Lại là xử lý chuỗi, nhưng có chút rắc rối. Đó là khi người sử dụng cung cấp nhiều cặp nháy kép, hoặc số nháy kép bị lẻ cặp, thì tui chưa tìm ra cách xử lý tốt nhất trong trường hợp này.

Một vấn đề khác nữa là sắp xếp kết quả tìm kiếm như thế nào để có thể trình bày theo thứ tự giảm dần về số lượng từ khoá so khớp (hay mức độ chính xác).

Xin các bác nhiều kinh nghiệm gợi ý giúp một vài cách giải quyết đơn giản và hiệu quả.
goldensea80 viết 01:41 ngày 10/10/2018
Cái này tìm tốt nhất là dùng Full text search, nó cho phép tìm kiếm và cho cả mức độ phù hợp. Tuy thế mình đang bị vướng lỗi font tiếng việt trong mySQL khi tìm kiếm theo kiểu này. Nếu tiếng Anh thì OK. Không biết có ai có kinh nghiệm giải quyết được font tiếng Việt trong mysql là OK.
sacroyant viết 01:39 ngày 10/10/2018
Tớ thì không bị vấn đề gì về font chữ cả. Ở phần tạo database, tớ luôn chọn Character Sets and Collations là utf8_unicode_ci. Các file PHP đều lưu ở dạng ANSI. Những trang trả kết quả về đều có thiết lập : header('Content-Type: text/html; charset=utf-8'); Bài viết thì được cập nhật bằng AJAX với encodeURIComponent cho mỗi giá trị post lên. Thế thôi chứ cũng không có gì đặc biệt.

Khi bạn view source các trang có ký tự tiếng Việt Unicode thì có thấy nó hiển thị chuẩn không ?
goldensea80 viết 01:51 ngày 10/10/2018
Quote Được gửi bởi sacroyant View Post
Tớ thì không bị vấn đề gì về font chữ cả. Ở phần tạo database, tớ luôn chọn Character Sets and Collations là utf8_unicode_ci. Các file PHP đều lưu ở dạng ANSI. Những trang trả kết quả về đều có thiết lập : header('Content-Type: text/html; charset=utf-8'); Bài viết thì được cập nhật bằng AJAX với encodeURIComponent cho mỗi giá trị post lên. Thế thôi chứ cũng không có gì đặc biệt.

Khi bạn view source các trang có ký tự tiếng Việt Unicode thì có thấy nó hiển thị chuẩn không ?
Ủa, mình thử trên localhost easyPHP, thử cả utf8_unicode_ci và utf8_general_ci mà sao vẫn bị nhỉ, thế nên không dùng được Fulltextsearch. Nếu vậy bạn thử Full text search đi, không khó đâu
sacroyant viết 01:49 ngày 10/10/2018
Tìm kiếm fulltext thì đơn giản quá còn gì. Nhưng có phải bao giờ người ta cũng muốn tìm chính xác cả cụm từ đâu. Đôi khi gõ vài ba từ gần nghĩa để gợi ý cho nó tìm thôi. Còn khi muốn giới hạn phạm vi thì mới thêm ngoặc kép như Google vậy.

Tớ làm được với 1 cụm rồi. Nhiều hơn 2 dấu nháy thì vẫn đành bỏ qua :

Không có ngoặc kép, trả về 21 kết quả :



Đặt trong ngoặc kép, chỉ còn 3 kết quả so khớp nguyên cụm từ :

pcdinh viết 01:46 ngày 10/10/2018
Đã trả lời bạn tại đây: http://groups.google.com/group/phpvi...4ed77c17f19af5
goldensea80 viết 01:48 ngày 10/10/2018
OK, thế thì bạn làm theo cách dưới đây. Mình đã áp dụng cho http://vui.ndvol.com/search.php và chạy tốt rồi!
Code:
<?php

$query = 'This is what "I have" been "searching for!"';
$keywords = array();

while (preg_match('/(?:"([^"]+)"|([^\s]+))/', $query, $quotes))
{
    $keywords[] = trim(isset($quotes[2]) ? $quotes[2] : $quotes[1]);
    $query = str_replace($quotes[0], null, $query);
}

echo '<pre>' . print_r($keywords, true) . '</pre>';

?>
sacroyant viết 01:52 ngày 10/10/2018
Cảm ơn các bác, em sẽ báo cáo kết quả sau khi thử thành công.
Bài liên quan
0