Full-text search với Sphinx Engine
Bài đăng này đã không được cập nhật trong 8 năm
Trong bài viết này mình xin giới thiệu tới mọi người Sphinx, một search engine rất nổi tiếng hỗ trợ full-text search. Mình cũng dùng được một thời gian nhưng chỉ ở mức độ chơi bời (lol)
Trang chủ: sphinxsearch.com
Về mặt kỹ thuật, Sphinx là một gói phần mềm độc lập cung cấp chức năng tìm kiếm toàn bộ văn bản với tốc độ nhanh, mà theo quảng cáo là:
- Tốc độ index:
- Nhanh hơn từ 50-100 lần MySQL FULLTEXT
- Nhanh hơn 4-10 lần so với external engines
- Tốc độ search:
- Nhanh hơn 1000 lần (wtf!) so với MySQL FULLTEXT trong một số trường hợp đặc biệt (Chẳng hạn như kết quả truy vấn lớn với GROUP BY)
- Nhanh hơn 2-10 lần so với external engines
Sphinx được thiết kế đặc biệt để tích hợp tốt với các cơ sở dữ liệu SQL, cũng như có thể dễ dàng truy cập bằng scripting languages. Tuy nhiên, Sphinx không phụ thuộc vào & cũng không yêu cầu bất kỳ database cụ thể nào để hoạt động.
Lập trình viên có thể truy cập vào Sphinx daemon (searchd) bằng cách sử dụng một trong ba phương pháp khác nhau để truy cập:
- Qua MySQL network protocol (sử dụng một ngôn ngữ có tên là SphinxQL)
- Thông qua API tìm kiếm bản địa ( SphinxAPI)
- Thông qua máy chủ MySQL với pluggable storage engine (SphinxSE)
1. Cài đặt
- Release Repository
- Trong bài viết này, mình sử dụng phiên bản Ubuntu 12.04 LTS x86_64 DEB.
sudo dpkg -i sphinxsearch_2.2.10-release-0ubuntu12-precise_amd64.deb
- Nếu xảy ra các lỗi:
Package libodbc1 is not installed.
Package unixodbc is not installed.
Package libpq5 is not installed.
Hãy chạy câu lệnh sau:
sudo apt-get install mysql-client unixodbc libpq5 libltdl7 odbcinst1debian2 libodbc1 odbcinst
2. Cấu hình
- Sau khi cài đặt hoàn tất, chúng ta có thư mục:
/etc/sphinxsearch
. Hãy sửa lại nội dung của file php-sphinx-search/demo/sphinx.conf trước khi thực hiện các câu lệnh bên dưới:
sudo cp php-sphinx-search/demo/sphinx.conf /etc/sphinxsearch/sphinx.conf
cd /etc/sphinxsearch
sudo mkdir data
sudo chmod -R 777 data
Tìm hiểu chi tiết hơn về cấu hình tại đây.
-
Một số kiến thức cơ bản cần lưu ý:
-
Để thực hiện indexing and re-indexing full-text. Về cở bản Sphinx sẽ đọc cấu hình trong file /etc/sphinxsearch/sphinx.conf. Khi chúng ta thực hiện các câu lệnh sau
sudo indexer --all
Or
sudo indexer --all --rotate
- Start sphinx service
sudo vim /etc/default/sphinxsearch
Đổi thành "START=yes"
.
Tiếp đến chúng ta khởi động Sphinx daemon:
sudo service sphinxsearch start
hoặc
sudo searchd
- Check Sphinx is listening port 9306:
netstat -anp | grep LIST
- Connect with mysql client:
mysql -h0 -P9306
3. Tích hợp
Để phục vụ cho việc chạy thử, mình có viết một package sau:
3.1. Cài đặt thư viện
PHP Sphinx Search Service Provider có thể được cài đặt thông qua Composer bằng cách thêm euclid1990/php-sphinx-search
package vào file composer.json
.
{
"require": {
"euclid1990/php-sphinx-search": "~1.0"
},
"minimum-stability": "stable"
}
Hoặc, chạy câu lệnh require package với composer:
composer require euclid1990/php-sphinx-search
Update packages với composer update
hoặc install với composer install
.
Để sử dụng, các bạn thêm vào boostrap autoload file:
require_once __DIR__ . '/../vendor/autoload.php';
use euclid1990\PhpSphinxSearch\SphinxSearch;
- Để cài đặt cho Laravel, xin vui lòng xem thêm tại: https://github.com/euclid1990/php-sphinx-search#2-for-laravel
3.2. Import Cơ sở dữ liệu
Mình có chuẩn bị sẵn cơ sở dữ liệu phục vụ cho việc chạy thử ứng dụng.
mysql -u{username} -p{password} {database} < php-sphinx-search/demo/blog.sql
3.3. Chạy !
Mình thử với đoạn code sau trong PHP/Laravel Framework.
$keywordEnglish = 'source code';
$keywordVietnamse = 'web nhanh mạnh';
$keywordJapanese = '私は です か';
$matchs = ['title', 'content'];
$table = 'posts';
$columns = ['id', 'user_id', 'title', 'content', 'created_at'];
// Facade class method
$resultEnglish = \SphinxSearch::search($keywordEnglish, $matchs, $table);
echo "Search results for English keyword: [$keywordEnglish].\n";
dump($resultEnglish->toArray());
$resultVietnamse = \SphinxSearch::search($keywordVietnamse, $matchs, $table);
echo "Search results for Vietnamese keyword: [$keywordVietnamse].\n";
dump($resultVietnamse->toArray());
$resultJapanese = \SphinxSearch::search($keywordJapanese, $matchs, $table);
echo "Search results for Japanese keyword: [$keywordJapanese].\n";
dump($resultJapanese->toArray());
// Helper
sphinx_search($keyword, $matchs, $table, $columns);
// Raw Query
$query = "SELECT id FROM posts WHERE MATCH('(@(title,content) source code)') LIMIT 1, 2";
sphinx_raw($query);
// Get sphinxQL
$sphinxQL = sphinx_ql();
$sphinxQL->select()->from($table)->execute();
// Get sphinxApi
$keyword = 'the source';
$tables = 'posts'
$resultApi = sphinx_api()->setMatchMode(SPH_MATCH_ANY)
->setFilter('category', [3])
->query($keyword, $table);
Kết quả thu được:
4. Làm gì tiếp theo ?
- Nghiên cứu thêm Document =))
- Lập lịch index cơ sở dữ liệu với cron job chẳng hạn )
- Trong hệ thống thực tế thì sẽ không chỉ có một server phụ trách việc tìm kiếm dữ liệu, lúc đó chúng ta cần tìm hiểu thêm về Distributed searching, Multiple indexes của Sphinx
All rights reserved