遭遇了 “黑天鹅” 事件
近期真是遭遇了 “黑天鹅” 事件,公司因卷入非法问题,面临一系列棘手处理,无奈之下只得遣散全体员工,我也因此瞬间失业。原本按部就班的工作节奏戛然而止,每天醒来,看着毫无安排的一天,心里满是茫然与失落。与其在这种不确定中焦虑徘徊,倒不如主动出击,给自己找点事儿做。我打算投身到文档撰写中,既能有效填补空闲时间,让生活重回正轨,也能借此梳理过往积累的知识与经验,为未来求职筑牢根基,让这段意外失业的日子,不至于虚度 。
什么是Sphinx? 有什么优缺点呢?
- phinx 是开源全文搜索引擎。
- 优点是高性能、功能丰富、可扩展性好、多语言支持、开源成本低;
- 缺点是配置复杂、对内存要求高、实时性有限、缺乏图形化管理界面。
安装和配置
- sphinx官网下载页面
- 服务器:CentOS7,glibc版本2.17
安装
# 创建存放sphinx软件目录 mkdir -p /usr/local/sphinx/ # 进入/usr/local/sphinx/文件夹 cd /usr/local/sphinx/ # 下载对应的glibc版本的sphinx软件包 wget https://sphinxsearch.com/files/sphinx-3.7.1-da9f8a4-linux-amd64-glibc2.17.tar.gz # 解压 tar -zxvf sphinx-3.7.1-da9f8a4-linux-amd64-glibc2.17.tar.gz
配置
# 进入到配置目录 cd /usr/local/sphinx/sphinx-3.7.1/etc/ # 创建文件,把配置粘贴进去 vim sphinx.conf ====================================================== # 通用配置部分,定义一些全局的设置 common { # 数据目录,用于存放索引文件和其他相关数据 datadir = ./sphinxdata } # 数据源配置,这里以 MySQL 数据库为例 source names_1_source { # 数据源类型为 MySQL type = mysql # 数据库主机地址,使用 127.0.0.1 以确保端口配置生效 sql_host = 127.0.0.1 # 数据库用户名 sql_user = active # 数据库密码 sql_pass = PcjcrN53sR8bdZyx # 要连接的数据库名 sql_db = active # 数据库端口号,默认是 3306 sql_port = 3306 # SQL 查询语句,用于从数据库中获取要索引的数据 sql_query = SELECT id, surname, name, first, second, gender, type, score, details FROM names_1 # 在执行查询前设置字符集为 UTF-8,确保中文等字符能正确处理 sql_query_pre = SET NAMES utf8mb4 } # 索引配置 index names_1_index { # 索引类型为普通索引 type = plain # 关联的数据源 source = names_1_source # 要进行全文搜索的字段 field = surname, details # 定义属性,用于排序、过滤等操作 attr_uint = gender, type # 无符号整数类型的属性 attr_float = score # 浮点数类型的属性 attr_string = name, first, second # 字符串类型的属性 # 字符集表,涵盖了数字、英文字母(大小写统一)、中文、日文、韩文等字符范围 # charset_table = # 最小词长度,设置为 1 表示单字符也会被索引,适用于中文和单字母搜索 min_word_len = 1 # 词形处理方式,这里设置为不进行词形处理 morphology = none # N - gram 长度,设置为 1 表示按单字符进行 N - gram 索引,有助于中文搜索 ngram_len = 1 # 指定用于 N - gram 索引的字符范围,这里包含了中文、日文、韩文等字符 ngram_chars = U+4E00..U+9FBB, U+3400..U+4DB5, U+20000..U+2A6D6, U+FA0E, U+FA0F, U+FA11, U+FA13, U+FA14, U+FA1F, U+FA21, U+FA23, U+FA24, U+FA27, U+FA28, U+FA29, U+3105..U+312C, U+31A0..U+31B7, U+3041, U+3043, U+3045, U+3047, U+3049, U+304B, U+304D, U+304F, U+3051, U+3053, U+3055, U+3057, U+3059, U+305B, U+305D, U+305F, U+3061, U+3063, U+3066, U+3068, U+306A..U+306F, U+3072, U+3075, U+3078, U+307B, U+307E..U+3083, U+3085, U+3087, U+3089..U+308E, U+3090..U+3093, U+30A1, U+30A3, U+30A5, U+30A7, U+30A9, U+30AD, U+30AF, U+30B3, U+30B5, U+30BB, U+30BD, U+30BF, U+30C1, U+30C3, U+30C4, U+30C6, U+30CA, U+30CB, U+30CD, U+30CE, U+30DE, U+30DF, U+30E1, U+30E2, U+30E3, U+30E5, U+30E7, U+30EE, U+30F0..U+30F3, U+30F5, U+30F6, U+31F0, U+31F1, U+31F2, U+31F3, U+31F4, U+31F5, U+31F6, U+31F7, U+31F8, U+31F9, U+31FA, U+31FB, U+31FC, U+31FD, U+31FE, U+31FF, U+AC00..U+D7A3, U+1100..U+1159, U+1161..U+11A2, U+11A8..U+11F9, U+A000..U+A48C, U+A492..U+A4C6 } # 搜索服务配置 searchd { # 监听的地址和端口,客户端通过此端口连接搜索服务 listen = 9312 # 搜索服务的日志文件路径,记录服务的运行信息 log = no # 查询日志文件路径,记录用户的查询请求,方便后续分析和优化 query_log = no # 进程 ID 文件路径,用于管理搜索服务进程 # pid_file = "" # 启用无缝索引切换,在重建索引时不影响搜索服务的正常运行 seamless_rotate = 1 # 是否预先打开所有索引文件,根据服务器内存和性能情况调整 preopen_indexes = 0 # 自动删除旧的索引文件,节省磁盘空间 unlink_old = 1 # 客户端连接超时时间(秒) client_timeout = 30 } ======================================================
测试 数据库active下的表names_1大概是这样的
启动sphinx和停止
# 可读权限
sudo chmod -R a+r /usr/local/sphinx/sphinx-3.7.1
# 启动
./searchd -c /usr/local/sphinx/sphinx-3.7.1/etc/sphinx.conf
# 停止
./searchd --stop -c /usr/local/sphinx/sphinx-3.7.1/etc/sphinx.conf
创建和更新索引
sudo chmod -R a+r /usr/local/sphinx/sphinx-3.7.1
sudo chmod u+w /usr/local/sphinx/sphinx-3.7.1/bin/indexer
cd /usr/local/sphinx/sphinx-3.7.1/bin/
./indexer -c /usr/local/sphinx/sphinx-3.7.1/etc/sphinx.conf --all --rotate
# ./indexer是 Sphinx 索引器程序。
# -c /usr/local/sphinx/sphinx-3.7.1/etc/sphinx.conf指定配置文件路径。
# --all对配置里所有索引操作。
# --rotate在searchd运行时无缝更新索引,不中断搜索服务。
查看端口和sphinx服务
# 查看端口
ps -ef | grep searchd|grep -v "grep"
netstat -an | grep 9312
# 对外防火墙放开端口
# 查询是否开启
sudo firewall-cmd --query-port=9312/tcp
# 开启
sudo firewall-cmd --add-port=9312/tcp --permanent
# 重启生效
sudo firewall-cmd --reload
php 使用
首先复制一份/usr/local/sphinx/sphinx-3.7.1/api/sphinxapi.php 文件到你的项目目录。
<?php declare(strict_types=1); require __DIR__.'./vendor/autoload.php'; require __DIR__."/sphinxapi.php"; use Fukuball\Jieba\Jieba; //use Fukuball\Jieba\Posseg; ini_set('memory_limit','512M'); //分词 Jieba::init(); //Posseg::init(); $searchQuery = 'Firaxis'; if (hasChinese($searchQuery)) { $cutWord = Jieba::cut($searchQuery); $searchQuery = implode('|', $cutWord); } echo '查找关键词:'.$searchQuery.'</br>'; // 创建 Sphinx 客户端对象 $cl = new SphinxClient(); // 设置 Sphinx 服务器的主机和端口 $cl->SetServer('127.0.0.1',9312); $t = $_GET['type'] ?? 1; switch ($t) { case 1: // 设置搜索的偏移量和返回结果数量 $cl->SetLimits(0, 10); // 设置排序模式为按相关性排序 $cl->SetSortMode(SPH_SORT_RELEVANCE); $index = 'names_1_index'; // $cl->SetFilterString('details','Firaxis'); $result = $cl->query($searchQuery, $index); if ($result === false) { echo '查询错误: '. $cl->GetLastError(); } else { // 处理查询结果 if ($result['total'] > 0) { foreach ($result['matches'] as $id => $match) { echo '文档ID: '. $id. ',姓名:'.$match['attrs']['name'].',score:'.$match['attrs']['score']. ',相关性得分: '. $match['weight']. '<br>'; // 可以根据索引中的字段获取更多信息 } } else { echo '没有找到匹配的结果'; } } break; case 2: //TODO 更新数据库 $index = 'names_1_index'; $attrs = ['score']; $values = [ 4048551 => [100], // 文档 ID 为 1 的文档,将 'price' 属性更新为 100 4048552 => [200] // 文档 ID 为 2 的文档,将 'price' 属性更新为 200 ]; $updated = $cl->UpdateAttributes($index, $attrs, $values); if ($updated >= 0) { echo "成功更新 $updated 条文档的属性。"; } else { echo "更新属性时出错: ". $cl->GetLastError(); } break; } function hasChinese($str) { for ($i = 0; $i < mb_strlen($str); $i++) { $char = mb_substr($str, $i, 1); $ord = mb_convert_encoding($char, 'UCS-2BE', 'UTF-8'); $code = hexdec(bin2hex($ord)); if ($code >= 0x4E00 && $code <= 0x9FA5) { return true; } } return false; }
One comment
立意高远,以小见大,引发读者对社会/人性的深层共鸣。