1.基本概念
1、 Index:索引库,文档的集合组成索引。和一般的数据库不一样,Lucene不支持定义主键,在Lucene中不存在一个叫做Index的类,通过IndexWriter来写索引,通过IndexReader来读索引。索引库在物理形式上一般是位于一个路径下的一系列文件。
2、 分析器(分词器):一段有意义的文字需要通过Analyzer分析器分割成一个个词语后才能按关键字搜索,StandardAnalyzer是Lucene中最常用的分析器。为了达到更好的搜索效果,不同的语言可以使用不同的搜索器(如IKAnalyzer是一个主要处理中文的分析器)。
3、 Analyzer返回的结果是一串Token,Token包含一个代表词本身含义的字符串和该词在文章中相应的起止偏移位置,Token还包含一个用来存储词类型的字符串。
4、 一个Document代表索引库中的一条记录,也叫做文档。要搜索的信息封装成Document后通过IndexWriter写入索引库,调用Searcher接口按关键词搜索后,返回的也是一个封装后的Document列表。
5、 一个Document可以包含多个列,叫做Field。例如一篇文章可以包含“标题”、“正文”、“修改时间”等Field。创建这些列对象以后,可通过Document的add方法增加这些列。与一般数据库不同,一个文档的一个列可以有多个值,例如一篇文档既可以术语互联网类,又可以属于科技类。
6、 Term是搜索语法的最小单位,复杂的搜索语法会分解成一个Term查询,他表示文档的一个词语,Term由两部分组成:它表示的词语和这个词语所出现的Field。
2.基本步骤
3.索引的创建
我们根据官网提供的demo一步步解析
3.1定义词法分析器
在以前的版本中需要里面指定参数,在新版本中放弃了这种方式
Analyzer analyzer = new StandardAnalyzer();
3.2确定索引文件的存储位置
lucene提供给我们两种方式进行存储
'''
// 存储索引到内存中:
Directory directory = new RAMDirectory();
// 存储索引到硬盘中 应该使用的方法:
//Directory directory = FSDirectory.open("/tmp/testindex");
'''
3.3创建IndexWriter,进行索引文件的写入
IndexWriterConfig是针对indexWriter的配置,其中只包括一个参数
IndexWriterConfig config = new IndexWriterConfig(analyzer);
IndexWriter iwriter = new IndexWriter(directory, config);
3.4内容提取,进行索引的存储
'''
Document doc = new Document();
String text = "This is the text to be indexed.";
doc.add(new Field("fieldname", text, TextField.TYPE_STORED));
iwriter.addDocument(doc);
iwriter.close();
第一行:创建一个document对象,索引库包括二部份:原始记录表,词汇表。这里的document对象相当于词汇表的一条空白的记录创建
第三行:第一个参数是:document对象中的属性名叫fieldname。 第二个参数是:存入词汇表中对应的内容。第三个参数表示该属性值是否是存入词汇表
第四行:把doc对象加入索引创建中。
第五行:关闭indexWriter,提交创建内容
4.关键字查询:
'''
DirectoryReader ireader = DirectoryReader.open(directory);
IndexSearcher isearcher = new IndexSearcher(ireader);
QueryParser parser = new QueryParser("fieldname", analyzer);
Query query = parser.parse("text");
TopDocs topDoc = isearcher.search(query, 10);
ScoreDoc[] hits = topDoc.scoreDocs;
第一行:读取索引
第二行:创建索引检索对象 统一利用IndexSearcher来解析
第三,四行: 创建Query 并将 text 关键字传入里面
第五,六行: 检索索引,获取符合关键字条件的前10条记录 query可以理解为sql里面的where条件
TopDocs这个类 如果我们要查找索引库中 "是" 这个关键字
从图中可以看到ScoreDocs里面保存着所有匹配索引的编号和分数
ScoreDoc源码
public float score; //索引获得的分数
public int doc; //索引号
public int shardIndex;
拿到索引号后 我们就能在searcher中查找索引所对应的Document
Document document = isearcher.doc(scoreDoc.doc);
根据我们存入的索引库字段 找到对应的值
document.get("fieldname");
最后 不要忘记关闭流
ireader.close();
directory.close();