lucene-NGram中文分词

本文介绍了一个使用Java实现的NGram分词器示例。通过Apache Lucene库中的NGramTokenizer类,该分词器能够对中文文本进行有效的切分,输出包括单字及双字组合的所有可能子串。这种方法适用于搜索引擎中的索引建立,能够帮助提高搜索的准确性和召回率。

NGram(综合了单词切分和二分法)

package busetoken;

import java.io.IOException;
import java.io.StringReader;

import org.apache.lucene.analysis.Token;
import org.apache.lucene.analysis.ngram.NGramTokenizer;

public class UseN {

/**
* @param args
*/
public static void main(String[] args) {
String s="编码规范从根本上解决了程序维护员的难题;规范的编码阅读和理解起来更容易,也可以快速的不费力气的借鉴别人的编码。对将来维护你编码的人来说,你的编码越优化,他们就越喜欢你的编码,理解起来也就越快。";
StringReader sr=new StringReader(s);

NGramTokenizer cjk=new NGramTokenizer(sr);
Token t=null;

try {
while ((t=cjk.next())!=null){
System.out.print(t.termText()+"|");
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// TODO Auto-generated method stub

}

}

效果如下:

编|码|规|范|从|根|本|上|解|决|了|程|序|维|护|员|的|难|题|;|规|范|的|编|码|阅|读|和|理|解|起|来|更|容|易|,|也|可|以|快|速|的|不|费|力|气|的|借|鉴|别|人|的|编|码|。|对|将|来|维|护|你|编|码|的|人|来|说|,|你|的|编|码|越|优|化|,|他|们|就|越|喜|欢|你|的|编|码|,|理|解|起|来|也|就|越|快|。|编码|码规|规范|范从|从根|根本|本上|上解|解决|决了|了程|程序|序维|维护|护员|员的|的难|难题|题;|;规|规范|范的|的编|编码|码阅|阅读|读和|和理|理解|解起|起来|来更|更容|容易|易,|,也|也可|可以|以快|快速|速的|的不|不费|费力|力气|气的|的借|借鉴|鉴别|别人|人的|的编|编码|码。|。对|对将|将来|来维|维护|护你|你编|编码|码的|的人|人来|来说|说,|,你|你的|的编|编码|码越|越优|优化|化,|,他|他们|们就|就越|越喜|喜欢|欢你|你的|的编|编码|码,|,理|理解|解起|起来|来也|也就|就越|越快|快。|

<think> 我们正在解决的问题是:如何让已建好的MySQL表支持中文全文索引。 根据引用,MySQL原生的全文索引不支持中文(或对中文支持有限),因此我们需要寻找替代方案。 引用[1]提到:尽量不用MySQL去做全文索引,如果需要大量搜索,建议通过coreseek(Sphinx的中文分支)或Lucene(如ElasticSearch)等工具辅助实现。 引用[2]指出:在MySQL中,使用全文索引需要配置最小搜索长度,并且对于中文,可以使用MySQL 5.7.6之后的版本(但需要第三方插件?)或者使用布尔模式进行修饰符搜索。 引用[3]提供了一个思路:将中文转换为英文,然后利用MySQL的全文索引检索英文,再通过关联表获取原始中文内容。 综合以上,我们可以给出以下解决方案: 1. 升级MySQL版本并使用内置的中文全文索引(如果版本较高,例如MySQL 5.7.6以上,并且安装了中文分词插件,如ngram)。 2. 使用外部搜索引擎(如Sphinx/Coreseek, Elasticsearch, Lucene等)。 3. 采用转换法:将中文内容转换为拼音或分词后的英文形式,然后利用MySQL的全文索引进行搜索。 由于用户的问题是“已建好的MySQL表支持中文”,这里我们重点讨论如何让MySQL表本身支持中文全文索引(即第一种和第三种方法),同时也会提到第二种方法作为备选。 具体步骤: 方法一:使用MySQL内置的ngram全文解析器(适用于MySQL 5.7.6及以上版本) 步骤: 1. 确认MySQL版本在5.7.6以上,并且支持ngram解析器。 2. 修改全文索引配置(如果需要): 在my.cnf文件中设置: [mysqld] ngram_token_size=2 # 通常设置为2,表示按两个字符分词(适用于中文词语) 3. 重建全文索引(因为表已存在,需要先删除旧的全文索引再创建新的): 例如: ```sql -- 删除旧的全文索引(如果有) ALTER TABLE table_name DROP INDEX index_name; -- 创建新的全文索引,使用ngram解析器 ALTER TABLE table_name ADD FULLTEXT INDEX index_name(column_name) WITH PARSER ngram; ``` 4. 查询时使用MATCH AGAINST语句,注意设置布尔模式(IN BOOLEAN MODE)或自然语言模式。 方法二:使用外部搜索引擎(如Elasticsearch) 这种方法不需要改变原有MySQL表结构,而是将数据同步到外部搜索引擎,利用其强大的中文分词和全文检索功能。 步骤: 1. 安装并配置Elasticsearch(或类似引擎)。 2. 安装中文分词插件(如IK Analyzer)。 3. 编写程序(或使用Logstash、Canal等工具)将MySQL数据同步到Elasticsearch。 4. 在应用中进行搜索时,不再查询MySQL,而是查询Elasticsearch。 方法三:转换法(将中文转换为英文分词) 步骤: 1. 创建一张分词表(索引表),用于存储原始表的中文内容转换后的英文分词。 2. 编写程序对原始表的中文内容进行分词(例如使用中文分词库如jieba),然后将分词结果转换为拼音或者英文关键词(也可以使用词库翻译成英文单词),存入分词表。 3. 在分词表上建立全文索引(英文的全文索引)。 4. 查询时,先将用户输入的中文关键词转换为英文分词,然后在分词表中搜索,再关联回原始表。 注意:方法三需要维护额外的索引表,且转换过程可能丢失语义,实现较为复杂。 根据用户的引用[3],有人采用这种方法,但需要额外的转换步骤。 推荐方法: 如果MySQL版本在5.7.6以上,推荐使用方法一(ngram解析器)最为直接。 如果版本低于5.7.6,考虑升级或者使用方法二(外部搜索引擎)。 如果无法升级且不能使用外部工具,则考虑方法三。 注意:引用[2]中提到需要配置最小搜索长度,在创建全文索引前需要确认配置(对于InnoDB表,修改`innodb_ft_min_token_size`,对于MyISAM表,修改`ft_min_word_len`)。但ngram解析器不受这个配置影响,因为它有自己的`ngram_token_size`。 操作示例(方法一): 假设我们有一个表`articles`,其中有一个`content`字段存储了中文内容,现在要为其创建全文索引。 Step 1: 检查MySQL版本 SELECT VERSION(); -- 确保>=5.7.6 Step 2: 修改配置文件(如需要,并重启MySQL) [mysqld] ngram_token_size=2 Step 3: 创建全文索引 -- 如果已有全文索引,先删除 ALTER TABLE articles DROP INDEX content_fulltext; -- 创建新的全文索引 ALTER TABLE articles ADD FULLTEXT INDEX content_fulltext(content) WITH PARSER ngram; Step 4: 查询 -- 自然语言模式 SELECT * FROM articles WHERE MATCH(content) AGAINST('关键词' IN NATURAL LANGUAGE MODE); -- 布尔模式(支持操作符,如+表示必须包含,-表示排除) SELECT * FROM articles WHERE MATCH(content) AGAINST('+关键词' IN BOOLEAN MODE); 注意:ngram解析器将文本按指定长度切分(例如2,就是按两个字符切分),所以查询时,关键词的长度最好与分词长度匹配或组合。例如,“中国”会被切分为“中”、“国”、“中国”(如果ngram_token_size=2,则每个词是两个字符,但中文每个字一个字符,所以两个字符就是两个连续的汉字)。因此,搜索单个字可能无效(如果ngram_token_size设置为2,则单个字不会被索引),所以设置ngram_token_size为1或2需要权衡。 如果设置ngram_token_size=1,则按单个字切分,这样搜索单个字也能命中,但索引会变大。 总结:对于已建好的MySQL表,支持中文全文索引的解决方案主要有三种,其中推荐使用MySQL 5.7.6及以上版本的内置ngram解析器。如果版本较低,则考虑外部搜索引擎或转换法。 下面生成相关问题。 </think> ### MySQL表支持中文全文索引的解决方案 MySQL原生全文索引对中文支持有限(5.7.6以下版本完全不支持),但可通过以下方法实现中文检索: #### 方法1:升级MySQL并使用ngram解析器(推荐) 1. **确认版本**:需MySQL 5.7.6+ 或 MariaDB 10.0.5+ 2. **修改配置**: ```ini [mysqld] ngram_token_size=2 # 按2个字符分词(适合中文) ``` 3. **重建索引**: ```sql ALTER TABLE 表名 DROP INDEX 原索引名, ADD FULLTEXT INDEX 新索引名(列名) WITH PARSER ngram; ``` 4. **查询语法**: ```sql SELECT * FROM 表名 WHERE MATCH(列名) AGAINST('关键词' IN BOOLEAN MODE); ``` > 此方案可直接处理中文分词(如"数据库"将被拆分为"数据"、"据库")[^2][^3] #### 方法2:使用转换法(兼容旧版本) 1. **新建索引表**: ```sql CREATE TABLE 索引表 ( id INT PRIMARY KEY, content_en TEXT -- 存储转换后的英文/拼音 ); ``` 2. **转换中文**: - 用程序(如Python+Jieba)将原文分词并转为拼音/英文 - 示例转换:"苹果手机" → "pingguoshouji" 3. **同步数据**: ```sql INSERT INTO 索引表(id, content_en) SELECT id, 转换函数(原文) FROM 原表; ``` 4. **创建索引**: ```sql ALTER TABLE 索引表 ADD FULLTEXT(content_en); ``` 5. **联合查询**: ```sql SELECT 原表.* FROM 原表 JOIN 索引表 ON 原表.id = 索引表.id WHERE MATCH(索引表.content_en) AGAINST('转换后的关键词'); ``` > 需维护数据同步,适合无法升级MySQL的场景[^3] #### 方法3:集成外部搜索引擎(高性能方案) ```mermaid graph LR A[MySQL] --> B[数据同步] --> C{搜索引擎} C --> D[ElasticSearch] C --> E[Sphinx/Coreseek] C --> F[Lucene] ``` 1. **工作流程**: - 使用Logstash/Canal同步MySQL数据到ElasticSearch - 安装IK Analyzer等中文分词插件 - 应用直接查询ElasticSearch获取ID,回MySQL查询明细 2. **优势**: - 支持复杂分词(同义词、停用词等) - 性能远超数据库级方案[^1] #### 配置注意事项 1. **最小词长设置**(通用): ```ini [mysqld] ft_min_word_len = 1 # MyISAM innodb_ft_min_token_size = 1 # InnoDB ``` 2. **重建索引**: ```sql REPAIR TABLE 表名 QUICK; -- MyISAM OPTIMIZE TABLE 表名; -- InnoDB ``` > 建议:MySQL 8.0+用户优先选用ngram方案(性能/维护成本均衡),海量数据场景推荐ElasticSearch组合方案[^1][^3] ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值