当前位置:网站首页>Lucene构建索引与执行搜索小记
Lucene构建索引与执行搜索小记
2022-06-09 05:18:00 【kaims】
构建索引
1.创建Directory对象,指定索引库存放位置
2.创建Analyzer对象,指定分析器类型
3.基于1和2创建IndexWriter对象
4.创建Document对象
5.创建Field对象,并将Field对象添加到Document对象中
6.使用IndexWriter对象将Document对象写入到索引库
7.关闭IndexWriter对象
Directory对象
Lucene中,Directory抽象类有两个子类,分别是RAMDirectory和FSDirectory。
SimpleFSDirectory类:FSDirectory的简单实现,并发能力有限,遇到多线程读同一个文件时会遇到瓶颈。NIOFSDirectory类:通过java.nio’s FileChannel实行定位读取,支持多线程读(默认情况下是线程安全的)。该类仅使用FileChannel进行读操作,写操作则是通过FSIndexOutput实现。 注意:NIOFSDirectory 不适用于Windows系统,另外如果一个访问该类的线程,在IO阻塞时被interrupt或cancel,将会导致底层的文件描述符被关闭,后续的线程再次访问NIOFSDirectory时将会出现ClosedChannelException异常,此种情况应用SimpleFSDirectory代替。RAMDirectory类:常驻内存的Directory实现方式。默认通过SingleInstanceLockFactory(单实例锁工厂)进行锁的实现。该类不适合大量索引的情况。另外也不适用于多线程的情况。 在索引数据量大的情况下建议使用MMapDirectory代替。RAMDirectory是Directory抽象类在使用内存最为文件存储的实现类,其主要是将所有的索引文件保存到内存中。这样可以提高效率。但是如果索引文件过大的话,则会导致内存不足,因此,小型的系统推荐使用,如果大型的,索引文件达到G级别上,推荐使用FSDirectory。MMapDirectory类:通过内存映射进行读,通过FSIndexOutput进行写的FSDirectory实现类。使用该类时要保证用足够的虚拟地址空间。另外当通过IndexInput的close方法进行关闭时并不会立即关闭底层的文件句柄,只有GC进行资源回收时才会关闭。
Analyzer对象
WhitespaceAnalyzer类:仅根据空白字符(whitespace)进行分词。KeywordAnalyzer类:不做任何分词,把整个原始输入作为一个token。所以可以看到输出只有1个token,就是原始句子。SimpleAnalyzer类:根据非字母(non-letters)分词,并且将token全部转换为小写。所以该分词的输出的terms都是由小写字母组成的。StopAnalyzer类:在SimpleAnalyzer的基础上增加了去除StopWords的功能。StandardAnalyzer类:基于JFlex进行语法分词(中文按字分,英文按空格分),然后删除停用词,并且将token全部转换为小写。ChineseAnalyzer类:性能类似于StandardAnalyzer,缺点是不支持中英文混和分词。CJKAnalyzer类:chedong写的CJKAnalyzer的功能在英文处理上的功能和StandardAnalyzer相同,但是在汉语的分词上,不能过滤掉标点符号,即使用二元切分。
Field对象
三大类属性:
- 是否分析:是否对域的内容进行分词处理。前提是我们要对域的内容进行查询。
- 是否索引:将Field分析后的词或整个Field值进行索引,只有索引方可搜索到。比如:商品名称、商品简介分析后进行索引,订单号、身份证号不用分析但也要索引,这些将来都要作为查询条件。
- 是否存储:将Field值存储在文档中,存储在文档中的Field才可以从Document中获取。比如:商品名称、订单号,凡是将来要从Document中获取的Field都要存储。
Field的各个子类就是实现了对不同类型字段的存储,同时选择了不同的字段属性,这里列举几个常用的:
TextField:存储字符串类型的数据。indexing+analyze;默认不存储原始数据。适用于需要全文检索的数据,比如邮件内容,网页内容等。StringField:存储字符串类型的数据。indexing但不analyze,即整个字符串就是一个token;默认不存储原始数据。适用于文章标题、人名、ID等只需精确匹配的字符串。IntPoint,LongPoint,FloatPoint,DoublePoint:用于存储各种不同类型的数值型数据。indexing;默认不存储原始数据。适用于数值型数据的存储。
执行搜索
https://www.cnblogs.com/leeSmall/p/9027172.html
1. 创建一个Directory对象,也就是索引库存放的位置
2. 创建一个DirectoryReader对象,需要指定Directory对象
3. 创建一个IndexSearcher对象,需要指定IndexReader对象
4. 创建Query对象,并执行查询
6. 返回查询结果,遍历查询结果并输出
7. 关闭DirectoryReader对象
Query对象
TermQuery:单关键字精确查询,注意TermQuery直接将搜索文本提交进行搜索,不进行analyze操作。
TermQuery tq = new TermQuery(new Term(“name", “thinkpad"));
RangeQuery:范围查询PhraseQuery:多关键字查询MultiPhraseQuery:多关键字查询,支持同位置多个词的OR匹配BooleanQuery:多条件查询
// 布尔查询
Query query1 = new TermQuery(new Term(filedName, "thinkpad"));
query1 = new TermQuery(new Term(filedName, "thinkpad"))
Query query2 = new TermQuery(new Term("simpleIntro", "英特尔"));
BooleanQuery.Builder booleanQueryBuilder = new BooleanQuery.Builder();
booleanQueryBuilder.add(query1, Occur.SHOULD);
booleanQueryBuilder.add(query2, Occur.MUST);
BooleanQuery booleanQuery = booleanQueryBuilder.build();
解析器
- 传统的解析器:
QueryParser和MultiFieldQueryParser
// 传统查询解析器-多默认字段
QueryParser parser = new QueryParser("defaultFiled", analyzer);
Query query = parser.parse("query String");
// 传统查询解析器-多默认字段
String[] multiDefaultFields = {
"name", "type", "simpleIntro" };
MultiFieldQueryParser multiFieldQueryParser = new MultiFieldQueryParser(multiDefaultFields, analyzer);
// 设置默认的组合操作,默认是 OR
multiFieldQueryParser.setDefaultOperator(Operator.OR);
Query query4 = multiFieldQueryParser.parse("笔记本电脑 AND price:1999900");
- 基于新的 flexible 框架的解析器:
StandardQueryParser
StandardQueryParser queryParserHelper = new StandardQueryParser(analyzer);
// 设置默认字段
// queryParserHelper.setMultiFields(CharSequence[] fields);
// queryParserHelper.setPhraseSlop(8);
// Query query = queryParserHelper.parse("a AND b", "defaultField");
Query query5 = queryParserHelper.parse("(\"联想笔记本电脑\" OR simpleIntro:英特尔) AND type:电脑 AND price:1999900","name");
边栏推荐
- 优视慕V8投影仪,打开高清新“视”界
- Practice and some ideas on the transformation of sonarlint code specification
- What did we do from March to April?
- Thinking of reading
- Faster RCNN
- How to build fastdfs, vsftpd and miniio file servers in marathon environment
- [it] Foxit PDF retention tool selection
- Differences between tinyint and int
- 崔健没变,北汽极狐该做出改变了
- [django learning notes - 12]: database operation
猜你喜欢
![[005] [esp32 Development Notes] ADF basic framework](/img/4a/45a3e467615be4b32531af64549cf2.png)
[005] [esp32 Development Notes] ADF basic framework

Camtasia studio2022 free key serial number installation trial detailed graphic tutorial

Clcnet: Rethink integrated modeling with classified confidence network (with source code download)

Product weekly report issue 28 | CSDN editor upgrade, adding the function of inserting existing videos

Cmdbuilding搭建简易流程及问题处理

Apache Devlake 代码库导览

ps如何给图像加白边

Recommend this UI automation testing framework and write use cases as colloquially as possible

How WPS ppt pictures come out one by one

Troubleshooting: MySQL containers in alicloud lightweight application servers stop automatically
随机推荐
优视慕V8投影仪,打开高清新“视”界
[005] [esp32 Development Notes] ADF basic framework
^25 processes and threads
2022年茶艺师(中级)考试题模拟考试题库及模拟考试
Typescript learning [6] interface type
Lighting - 光的亮度衰减
Linked list
An article takes you to know what token is
^26 browser kernel
模式识别大作业——PCA&Fisher&KNN&Kmeans
Vector of STL
What did we do from March to April?
Penetration test path dictionary, blasting dictionary
^25进程与线程
readme. md
ps如何给图像加边框
Analysis of semaphore source code of AQS
Ribbon和Feign的对比-带简易例子
ETF operation practice record: March 2, 2022
Kube dns yaml