Full-text search với Sphinx Engine

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

Indexer

  • 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

Searchd

  • Check Sphinx is listening port 9306:
netstat -anp | grep LIST
  • Connect with mysql client:
mysql -h0 -P9306

Connect via MySQL Client

3. Tích hợp

Để phục vụ cho việc chạy thử, mình có viết một package sau:

PHP Sphinx Search Latest Stable Version Total Downloads License

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;

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:

Click to view Result

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