lucene 从0到1

Lucene[‘lusen] 是一个高性能的 java 全文检索工具包(引擎),现阶段 Apache 的顶级的开源项目,可基于它开发出各种全文搜索的应用。
一个全文检索系统需要做的可以分为两部分,第一部分是建立索引,第二部分是进行检索。下面就结合代码对这两部分进行讲解。

先创建一个由 maven 管理的 java 项目,在 pom 中添加 lucene 依赖

<dependencies>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.11</version>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>org.apache.lucene</groupId>
        <artifactId>lucene-core</artifactId>
        <version>${lucene.version}</version>
    </dependency>

    <dependency>
        <groupId>org.apache.lucene</groupId>
        <artifactId>lucene-queryparser</artifactId>
        <version>${lucene.version}</version>
    </dependency>
</dependencies>

然后

mvn clean install

把各种依赖导入

建立索引

建立索引是从原始文档到索引文件的过程,索引中包含索引和文档对象。每个文档对象有唯一的 id,文档对象里包含了很多 field,每个 field 有自己的名字(可重复)和相应的值。索引的最小单位是 Term,可以理解为分词之后的每个单词或者不进行分词的整体,也可以建立 n-gram 的 term。
常用的 Field 类如下:

Field 类数据类型是否分词是否索引是否存储备注
StringField(FieldName, FieldValue,Store.YES))StringNoYesYes or No用于不进行分词的字符串,如订单号
LongField(FieldName, FieldValue,Store.YES)longYesYesYes or No
StoredField(FieldName, FieldValue)重载方法,支持多种类型NoNoYes需要储存的文档信息,但不进行索引和分词
TextField(FieldName, FieldValue, Store.NO)StringYesYesYes or No需要储存的正文内容
TextField(FieldName, reader)streammingYesYesNo因为是流,lucene猜测内容比较多,会采用Unstored

建立索引,第一步当然就是创建索引对象

Directory index = FSDirectory.open(Paths.get(indexPath));

因为有些内容需要分词,所以也需要建立文本分析器对象,并把它加入到索引 Writer 的配置中配置 IndexWriter,也对增量更新(IndexWriterConfig.OpenMode.APPEND、IndexWriterConfig.OpenMode.CREATE_OR_APPEND)还是全量更新(IndexWriterConfig.OpenMode.CREATE)进行设置:

Analyzer analyzer = new StandardAnalyzer();
IndexWriterConfig config = new IndexWriterConfig(analyzer);
config.setOpenMode(IndexWriterConfig.OpenMode.CREATE);
IndexWriter writer = new IndexWriter(index, config);

下面就可以对索引进行写操作了,对于每个文档:

// 先创建一个文档(Document 对象)
Document doc = new Document();
// 解析原始文本并往文档中添加相应的 Field
Field pathField = new StringField("path", file.toString(), Field.Store.YES);
Field contentsField = new TextField("contents", buffer.toString(),Field.Store.YES);
doc.add(pathField);
doc.add(contentsField);
writer.addDocument(doc);

最后记得把该关的都关了

index.close();
writer.close();

建立后查看索引内内用

有一个开源项目可以查看索引文件,项目地址:https://github.com/DmitryKey/luke
克隆后进入文件夹“mvn install”,然后

java target/luke-swing-with-deps.jar

会弹出UI界面,选择索引所在文件夹,就可饮查看索引和进行一些简单的操作了。

进行查询

进行查询,首先要创建 IndexReader 对象来读取索引,并且把它交给 IndexSearcher 对象来进行搜索

IndexReader reader = DirectoryReader.open(FSDirectory.open(Paths.get(indexPath)));
IndexSearcher searcher = new IndexSearcher(reader);

对于输入的 String 类型的 query 我们需要对其解析成 IndexSearcher 可以查询的 query 类型

Analyzer analyzer = new StandardAnalyzer();
QueryParser parser = new QueryParser(field, analyzer);
Query query = parser.parse(raw_input);

进行搜索

TopDocs results = searcher.search(query, 10);// 搜索结果,包含了一些搜索的信息
ScoreDoc[] hits = results.scoreDocs;// 搜索所得结果的列表
int numTotalHits = Math.toIntExact(results.totalHits);//一共所得的结果
for (ScoreDoc hit : hits) {
    int docID = hit.doc;
    Document document = searcher.doc(docID);
    System.out.println("文档:" + document.get("path"));
    System.out.println(document.getField("contents").stringValue());
    System.out.println("相关度:" + hit.score);
    System.out.println("================================");
}

搜索常用的方法,评分应该是根据idf来算的

方法说明
IndexSearcher.search(query, n)根据 query 搜索评分最高的 n 条记录
IndexSearcher.search(query, filter, n)添加过滤策略
IndexSearcher.search(query, n, sort)添加排序策略
IndexSearcher.search(query, filter, n, sort)添加过滤策略和排序策略

最后把该关的都关了

reader.close();
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值