再来看一下 词法分析器 lucene分析器

本文介绍Lucene中的分析器、分词器及过滤器的概念与应用,并探讨了中文分词技术的不同方法,包括n元切分、最长匹配、最大压缩及统计语言模型等。此外还提供了Lucene分析器的测试代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

概念:

 

分析器Analyzer
分词器Tokenizer
过滤器Filter
Tokenizer负责把词分开
Filter负责对分开的词进行处理
Analyzer包装组合Tokenizer和Filter以满足特定的分词需求

 

几种不同的分析器:

WhitespaceAnalyzer();
SimpleAnalyzer();
StopAnalyzer();
StandardAnalyzer();

重点是StandardAnalyzer();

 

中文分词的理解

中文与西方文字不同,西方文字如英文的单词间有空格作为分隔,计算机很容易把一个个词分开。而中文句子里的之间没有分隔,要把中文句子拆分成词就需要使用中文分词技术。由于全文索引采用的是倒排索引技术,所以分词的效果直接决定了搜索的效果。
目前的中文分词技术主要有:n元切分、最长匹配、最大压缩、统计语言模型等方法。n元切分,即机械切分。就是把中文句子每n个字分成一个“词”。比 如,“我是大学生”用一元切分的结果就是“我”、“是”、“大”、“学”、“生”。二元分词如果采用串分割,结果就是“我是”、“大学”、“生”,采用交 叉分割结果就是“我是”、“是大”、“大学”、“学生”。通常,都采用交叉切分,以免在搜索“学生”时无法搜索到结果。同时,交叉分割可以保证查询和索引 切分的一致性。但交叉分割的索引大小是串分割的n倍。机械切分并不是真正意义上的中文分词,因为它并没有把句子根据词法和语义分成有意义的词。这种方法实 现简单,切分效率高,但会产生很多无用词。Lucene自带的StandardAnalyzer对中文的切分就是一元切分。Lucene Sandbox中的CJKAnalyzer采用的是交叉二元分词。
最长匹配法是使用词典来切分的。比如,“我是大学生”根据词典通常会被拆分 为“我”、“是”、“大学生”。最长匹配法又分正向最长匹配和反向最长匹配,即从句子的正方向或方向匹配单词。通常反向最长匹配的效果要好于正向最长匹 配。也可以把两者结合起来,即双向最长匹配。最长匹配法实现也较简单,分词速度较快,但准确率比较低。采用词典的分词方法的效果很大程度上取决于词典的质 量。同时,在遇到词典中没有的词往往就束手无策了。而且,基于词典的分词对于新词,还有人名、地名等往往不能很好地识别。Lucene Sandbox中的ChineseAnalyzer就是采用的反向最长匹配。
统计语言模型方法简单的说,就是通过从文本库中统计出字与字之间 结合和分开的概率来分词的。比如“我是大学生”,“是”和“大”结合的概率要小于“大”和“学”结合的概率。这种方法不依赖于词库和语法定义,可以适应新 词以及人名地名等。但实现复杂,分词速度慢。在上下文信息较少的情况下效果不够好。

 

lucene分析器测试代码

 

1:对空格进行了分词
2:大写都转换成小写

3:对停止词的过滤如a,an ,the 等小词

4:删除了所有的标点符号

 

 

lucene常用搜索排序摘录
一,查询

 

一个关键字,对一个字段进行查询

 

Java代码

模糊查询

 

Java代码

一个关键字,在两个字段中查询
1.BooleanClause.Occur[]的三种类型: MUST : + and MUST_NOT : - not SHOULD : or
2.下面查询的意思是:content中必须包含该关键字,而title有没有都无所谓
3.下面的这个查询中,Occur[]的长度必须和Fields[]的长度一致。每个限制条件对应一个字段

 

Java代码

两个(多个)关键字对两个(多个)字段进行查询,默认匹配规则
1.关键字的个数必须和字段的个数相等
2.由于没有指定匹配规定,默认为"SHOULD" 因此,下面查询的意思是:"title"中含有keyword1 或 "content"含有keyword2。在此例中,把keyword1和keyword2相同

 

Java代码

两个(多个)关键字对两个(多个)字段进行查询,手工指定匹配规则
1.必须 关键字的个数 == 字段名的个数 == 匹配规则的个数
2.下面查询的意思是:"title"必须不含有keyword1,并且"content"中必须含有keyword2


Java代码

 

对数字范围进行查询
1.两个条件必须是同一个字段
2.前面一个条件必须比后面一个条件小,否则找不到数据
3.new RangeQuery中的第三个参数,表示是否包含"=" true: >= 或 <= false: > 或 <
4.找出 55>=id>=53 or 60>=id>=57:

 

Java代码

二:结果排序 

排序的关键点有两个:
1:首先你要排序的字段必须是被index的,并且是untokenized的。如:

 

Java代码

2:在检索时候:如:  
排序
1.被排序的字段必须被索引过(Indexecd),在索引时不能 用 Field.Index.TOKENIZED (用UN_TOKENIZED可以正常实现.用NO时查询正常,但排序不能正常设置升降序)
2.SortField类型 SCORE、DOC、AUTO、STRING、INT、FLOAT、CUSTOM 此类型主要是根据字段的类型选择
3.SortField的第三个参数代表是否是降序true:降序  false:升序

 

Java代码

 

按日期排序

 

Java代码


过滤器

 

Java代码

--------------------------------------------------

 

默认情况下,IndexSearcher类的search方法返回查询结果时,是按文档的分值排序的,可以使用重载的search方法对结果排序
IndexSearcher.search(Query,Sort);
new Sort() 和 Sort.RELEVANCE,以及null一样,采用默认排序,要定义排序字段,方法是将字段传入Sort对象
Sort sort = new Sort(String field);
也可以对多个字段排序Sort sort = new Sort(String[] fields);
例:
Sort sort = new Sort(new SortField[]{new SortField(“title”),new SortField(“name”)});
Hits hits=searcher.search(query,Sort);

多字段查找MultiFieldQueryParser
只在某些Term中查找,不关心在哪个字段
Query query = new MultiFieldQueryParser.parse(“word”,new String[]{“title”,”content”},analyzer); //在title和content中找word
多字段时默认是OR关系,要改变它,使用以下方法:
Query query = MultiFieldQueryParser.parse(“word”,new String[]{“title”,”content”},new int[]{MultiFieldQueryParser.REQUIRED_FIELD,MultiFieldQueryParser.PROHIBITED_FIELD},analyzer);
其中:
REQUIRED_FIELD 表示该条件必须有
PROHIBITED_FIELD 表示必须不含

搜索多个索引文件MultiSearcher
1) 建立多个索引:使用不同的索引目录,实例化不同的IndexWriter
2) 建立多索引搜索器:
Searcher[] searchers = new SEARCHER[2];
Searchers[0] = new IndexSearcher(dir1); //搜索索引目录一
Searchers[1]= new IndexSearcher(dir2);//搜索索引目录二
Searcher searcher = new MultiSearcher(serarchers);

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值