给全文搜索引擎Manticore (Sphinx) search 增加中文分词

简介: Sphinx search 是一款非常棒的开源全文搜索引擎,它使用C++开发,索引和搜索的速度非常快,我使用sphinx的时间也有好多年了。最初使用的是coreseek,一个国人在sphinxsearch基础上添加了mmseg分词的搜索引擎,可惜后来不再更新,sphinxsearch的版本太低,bug也会出现;后来也使用最新的sphinxsearch,它可以支持几乎所有语言,通过其内置的ngram tokenizer对中文进行索引和搜索。

QQ_20190314094950

Sphinx search 是一款非常棒的开源全文搜索引擎,它使用C++开发,索引和搜索的速度非常快,我使用sphinx的时间也有好多年了。最初使用的是coreseek,一个国人在sphinxsearch基础上添加了mmseg分词的搜索引擎,可惜后来不再更新,sphinxsearch的版本太低,bug也会出现;后来也使用最新的sphinxsearch,它可以支持几乎所有语言,通过其内置的ngram tokenizer对中文进行索引和搜索。

但是,像中文、日文、韩文这种文字使用ngram还是有很大弊端的:

当Ngram=1时,中文(日文、韩文)被分解成一个个的单字,就像把英文分解成一个个字母那样。这会导致每个单字的索引很长,搜索效率下降,同时搜索结果习惯性比较差。

当Ngram=2或更大时,会产生很多无意义的“组合”,比如“的你”、“为什”等,导致索引的字典、索引文件等非常大,同时也影响搜索速度。

基于以上弊端,为中日韩文本加入分词的tokenizer是很有必要的。

于是决定来做这件事。先去Sphinxsearch网站去看看,发现它已经发布了新的3.x版本,而且加入了很多很棒的特性,然而它从Sphinxsearch 3.x 开始,暂时不再开源. 不过,部分前Sphinxsearch的开发人员跳出来成立新团队,在Sphinx 2.x版本基础上开发自己的Manticoresearch。这两者很像,从它们的名字就可以看出来,这俩都是狮身怪兽。

Sphinx 是(古埃及)狮身人面像,Manticore 是(传说中的)人头狮身龙(蝎)尾怪兽

Manticoresearch 从Sphinxsearch 继承而来, 并做了性能优化. 因此,我选择了Manticoresearch 来添加中日韩分词。

首先从Manticoresearch的github仓库pull最新的代码来谈价,后面我也会尽力与Manticoresearch的主分支保持同步。

算法实现

算法基于字典,具体是cedar的实现的双数组trie。cedar是C++实现的高效双数组trie,也是分词字典的最佳之选。cedar的协议是GNU GPLv2, LGPLv2.1, and BSD;或者email联系作者所要其它协议。

通过最小匹配(而非单字)来匹配字典和字符串,把字符串分割成最短(而非单字)的词。如果遇到处理不了的歧义时,以单字做词。这样的目的是,保证搜索时能找到这些内容而不丢失。

稍微解释一下,对于搜索引擎的分词为什么这么做:

搜索引擎要能找到尽可能全内容:最彻底的方法是ngram=1,每个字单独索引,这样你搜索一个单字“榴”时,含有“榴莲”的文本会被找到,但缺点就如前面所说。
搜索引擎要能找到尽可能相关的内容: 分词就是比较好的方法,对词进行索引,这样你搜索一个单字“榴”时,含有“榴莲”的文本就不会被找到。但分词的粒度要小,比如“编程语言”这是一个词组,如果把这个分成一个词,你搜索“编程”时,就找不到只含“编程语言”的文本,同样的,“上海市”要分成“上海”和“市”,等等。所以,“最小匹配”适用于搜索引擎。
编译安装

从github仓库manticoresearch-seg获取源码,编译方法跟Manticoresearch一样,具体看官方文档。

使用方法

  1. 准备词表 把所有词写到一个txt文件,一行一个词,如下所示:
# words.txt
中文
中国語
중국어
  1. 创建字典 成功编译代码后,就会得到创建字典的可执行程序make_segdictionary. 然后执行命令:
./make_segdictionary words.txt words.dict

这样就得到了字典文件: words.dict

  1. 配置索引 只需在配置文件的 index {...} 添加一行即可:
index {
    ...
    seg_dictionary = path-to-your-segmentation-words-dictionary
    ...
}

提醒: 分词对批量索引和实时索引都起作用。

吐槽

添加分词最初的想法是,我的代码作为新增文件加入项目,只在原有文件个别处添加就好。这样做分得比较清楚,后面对manticore官方仓库提交代码也比较清晰。于是就尝试这样做。

然而,Sphinx的代码组织的真是有点乱,Manticore沿用Sphinx的代码所以架构是一样的。最大的一个cpp文件sphinx.cpp 竟然有3万多行代码,很多类的声明直接放在这个.cpp 文件里面,而没有放到头文件sphinx.h里面。 因为我实现的分词tokenizer必须要继承它的类保持接口一致。尝试着把cpp文件的一些声明移到.h文件,结果是越移越多,要对原始文件做很大改动,甚至可能要重新架构源代码。不是不可以重新架构,一来会很费时间,二来向官方提交代码很难被接受,三是跟官方代码保持同步就很费劲,最终还是在原来sphinx.cpp文件中添加分词tokenizer: CSphTokenizer_UTF8Seg 。

当然,Sphinx的代码的类的继承关系比较清晰,继承原来的tokenizer实现新的也不算费事,修改了4个源码文件就添加好了分词tokenizer。

文章来自于猿人学博客:Python教程

目录
相关文章
|
自然语言处理 搜索推荐 Java
号称elastic seaech 100多倍性能的Manticore search搜索引擎有多强
号称elastic seaech 100多倍性能的Manticore search搜索引擎有多强
2075 0
|
机器学习/深度学习 搜索推荐 关系型数据库
号称Elasticsearch 10倍性能搜索引擎到底有多强悍
号称Elasticsearch 10倍性能搜索引擎到底有多强悍
734 0
|
存储 Android开发 Python
使用 MitmProxy 自动抓取微信公众号阅读数、点赞和再看数据(一)
某天接到一个需要抓取某某微信公众的所有历史文章的阅读数、点赞和再看数据的需求。 为了解放双手,就用 Python 代码撸一个,选择 MitmProxy 代理作为抓包工具,因为它可以使用 Python 代码监听抓取到的 url,用于自动获取 cookie 等场景。
2143 0
使用 MitmProxy 自动抓取微信公众号阅读数、点赞和再看数据(一)
|
5月前
|
人工智能 持续交付 开发工具
AI大模型运维开发探索第五篇:GitOps 智能体
本文探讨了如何结合 Manus 的智能体设计理念与 GitOps 持续集成技术,构建低成本、高扩展性的智能体系统。通过借鉴 Manus 的沙箱机制与操作系统交互思路,利用 Git 作为智能体的记忆存储与任务调度核心,实现了推理过程可视化、自进化能力强的智能体架构。文章还分享了具体落地实践与优化经验,展示了其与 Manus 相当的功能表现,并提供了开源代码供进一步探索。
418 20
|
并行计算
ERROR: cuda requested, but not all dependencies are satisfied: ffnvcodec
ERROR: cuda requested, but not all dependencies are satisfied: ffnvcodec
766 0
|
SQL 存储 自然语言处理
sphinx(一)全文检索引擎sphinx
Sphinx是一个基于SQL的全文检索引擎,可以结合MySQL,PostgreSQL做全文搜索,它可以提供比数据库本身更专业的搜索功能,使得应用 程序更容易实现专业化的全文检索。Sphinx特别为一些脚本语言设计搜索API接口,如PHP,Python,Perl,Ruby等,同时为MySQL 也设计了一个存储引擎插件。
874 0
sphinx(一)全文检索引擎sphinx
|
C# 容器 Android开发
WPF字体图标——IconFont
原文:WPF字体图标——IconFont 版权声明:本文为【CSDN博主:松一160】原创文章,未经允许不得转载。 https://blog.csdn.net/songyi160/article/details/54894233 一、字体图标概述 ①字体图标其实就是把矢量图形打包到字体文件里,以后就可以像使用一般外置字体一样的使用它,因此Winform、WPF中都是可以用的。
2748 0
|
存储 关系型数据库 MySQL
深入MySQL:事务日志redo log详解与实践
【8月更文挑战第24天】在MySQL的InnoDB存储引擎中,为确保事务的持久性和数据一致性,采用了redo log(重做日志)机制。redo log记录了所有数据修改,在系统崩溃后可通过它恢复未完成的事务。它由内存中的redo log buffer和磁盘上的redo log file组成。事务修改先写入buffer,再异步刷新至磁盘,最后提交事务。若系统崩溃,InnoDB通过redo log重放已提交事务并利用undo log回滚未提交事务,确保数据完整。理解redo log工作流程有助于优化数据库性能和确保数据安全。
1116 0
|
Linux
Centos7.4升级7.9失败,救援:/boot目录下文件丢失error: file ‘/initramfs-3.10.0-957.el7.x86_64.img‘ not found
以上步骤应该可以帮助你解决问题。如果问题仍然存在,可能需要更深入的排查。
514 1