Lucene构建索引与执行搜索小记

构建索引

  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();

解析器

  • 传统的解析器:QueryParserMultiFieldQueryParser
// 传统查询解析器-多默认字段
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");
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值