Lucene教程--维护索引、查询对象和相关度排序

2023-12-15 09:32

本文主要是介绍Lucene教程--维护索引、查询对象和相关度排序,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

索引维护

1.1 添加索引

步骤:

1)创建存放索引的目录Directory

2)创建索引器配置管理类IndexWriterConfig

3)使用索引目录和配置管理类创建索引器

4)使用索引器将Document写到索引文件中

代码:

// 定义索引存储目录Directory directory = FSDirectory.open(new File(indexFolder));//标准分析器Analyzer standardAnalyzer = new StandardAnalyzer();IndexWriterConfig indexWriterConfig = new IndexWriterConfig(Version.LUCENE_4_10_3,standardAnalyzer);// 定义索引操作对象IndexWriter indexWriter = new IndexWriter(directory,indexWriterConfig);//遍历目录下的文档,创建DocumentList<Document> docs = IndexUtils.file2Document(indexSource);// 遍历目录 下的文件生成的文档,调用indexWriter方法创建索引for (Document document : docs) {indexWriter.addDocument(document);}// 索引操作流关闭indexWriter.close();

1.2 删除索引

1)删除符合条件的索引

// 索引目录Directory directory = FSDirectory.open(new File(indexFolder));// 定义索引操作对象IndexWriter indexWriter = new IndexWriter(directory,new IndexWriterConfig(Version.LUCENE_4_10_3,new StandardAnalyzer()));// 删除索引,文件名称等于“springmvc.txt”的索引删除indexWriter.deleteDocuments(new Term("fileName", "springmvc.txt"));//索引删除后无法恢复indexWriter.commit();// 关闭索引操作流indexWriter.close();

说明:根据Term项删除索引,满足条件的将全部删除,建议参照关系数据库基于主键删除方式,所以在创建索引时需要创建一个主键Field,删除时根据此主键Field删除。

索引删除后将放在Lucene的回收站中,Lucene3.X版本可以恢复删除的文档,3.X之后无法恢复。

2)删除全部索引

// 索引目录Directory directory = FSDirectory.open(new File(indexFolder));// 定义索引操作对象IndexWriter indexWriter = new IndexWriter(directory,new IndexWriterConfig(Version.LUCENE_4_10_3,new StandardAnalyzer()));//删除全部索引indexWriter.deleteAll();

说明:将索引目录的索引信息全部删除,直接彻底删除,无法恢复。

1.3 更新索引

// 索引目录Directory directory = FSDirectory.open(new File(indexFolder));// 定义索引操作对象IndexWriter indexWriter = new IndexWriter(directory,new IndexWriterConfig(Version.LUCENE_4_10_3,new StandardAnalyzer()));// 创建更新文档Document doc_update = new Document();Field field_fileName = new TextField("fileName", "springmvc.txt",Store.YES);doc_update.add(field_fileName);// 根据条件更新索引,将fileName等于“springmvc_test.txt”的更新为上边的文档// 更新的机制 是先删除再添加,如果原根据fileName没有找到“springmvc_test.txt”,则添加新文档indexWriter.updateDocument(new Term("fileName", "springmvc_test.txt"),doc_update);//提交indexWriter.commit();//关闭indexWriter.close();

说明:更新索引是先删除再添加,建议对更新需求采用此方法并且要保证对已存在的索引执行更新,可以先查询出来,确定更新记录存在执行更新操作。

Query和QueryParser

2.1 创建查询的两种方法

创建查询

对要搜索的信息创建Query查询对象,Lucene会根据Query查询对象生成最终的查询语法,类似关系数据库Sql语法一样Lucene也有自己的查询语法,比如:“name:lucene”表示查询Field的name为“lucene”的文档信息。

可通过两种方法创建查询对象:

1)使用Lucene提供Query子类

Query是一个抽象类,lucene提供了很多查询对象,比如TermQuery项精确查询,NumericRangeQuery数字范围查询等。

如下代码:

Query query = new TermQuery(new Term("name", "lucene"));

2)使用QueryParse解析查询表达式

QueryParse会将用户输入的查询表达式解析成Query对象实例。

如下代码:

QueryParser queryParser = new QueryParser("name", new IKAnalyzer());Query query = queryParser.parse("name:lucene");

2.2 通过Query 搜索

2.2.1 TermQuery

TermQuery,通过项查询,TermQuery不使用分析器所以建议匹配不分词的Field域查询,比如订单号、分类ID号等。

//创建查询对象Query query = new TermQuery(new Term("fileName", "springmvc_test.txt"));//搜索索引 目录Directory directory = FSDirectory.open(new File(indexFolder));//定义IndexReaderIndexReader reader = DirectoryReader.open(directory);//创建indexSearcherIndexSearcher indexSearcher = new IndexSearcher(reader);//执行搜索TopDocs topDocs = indexSearcher.search(query, 100);

2.2.2 NumericRangeQuery

NumericRangeQuery,指定数字范围查询,如下:

//文件大小在0到1024的文件NumericRangeQuery<Long> numericRangeQuery = NumericRangeQuery.newLongRange("fileSize", 0l, 1024l, true, true);

2.2.3 BooleanQuery

BooleanQuery,布尔查询,实现组合条件查询,如下:

// 数字范围查询NumericRangeQuery<Long> numericRangeQuery = NumericRangeQuery.newLongRange("fileSize", 0l, 1024l, true, true);//定义Boolean查询BooleanQuery booleanQuery = new BooleanQuery();//必须满足fileSize在0到1024范围的条件booleanQuery.add(numericRangeQuery, Occur.MUST);//根据文件名搜索Query query = new TermQuery(new Term("fileName", "springmvc.txt"));//不查询文件名为“springmvc_test.txt”booleanQuery.add(query, Occur.MUST);IndexReader reader = DirectoryReader.open(directory);IndexSearcher searcher = new IndexSearcher(reader);TopDocs topDocs = searcher.search(booleanQuery, 100);

说明:

Occur.MUST 查询条件必须满足,相当于and

Occur.SHOULD 查询条件可选,相当于or

Occur.MUST_NOT 查询条件不能满足,相当于not非

2.2.4 MatchAllDocsQuery

使用MatchAllDocsQuery查询索引目录中的所有文档,如果只存在过滤而没有查询条件时可以使用此类定义Query,如下:

//查询全部文档Query query = new MatchAllDocsQuery();

2.3 通过QueryParser搜索

通过QueryParser也可以创建Query,QueryParser提供一个Parse方法,此方法可以直接根据查询语法来查询。Query对象执行的查询语法可通过System.out.println(query);查询。

Lucene查询语法官方介绍:

http://lucene.apache.org/core/4_0_0/queryparser/org/apache/lucene/queryparser/classic/package-summary.html

2.3.1 QueryParser查询

QueryParser使用方法:

 

//f是默认搜索的域QueryParser queryParser = new QueryParser("f", analyzer);// 指定查询语法 ,如果不指定fileName就搜索默认的域Query query2 = queryParser.parse("fileName:springmvc.txt");或:Query query2 = queryParser.parse("spring AND web");

上边介绍的基于类的查询方法,使用QueryParser可用下边的查询语法 实现,

项查询:

FieldName : value

范围查询:

FieldName:[min TO max]

注意:QueryParse不支持对数字范围的搜索,它支持字符串范围。数字范围搜索建议使用NumericRangeQuery。

组合查询:

上边BooleanQuery例子的查询表达式如下:

+fileSize:[0 TO 1024] +fileName:springmvc.txt

上边的表达式表示fileSize的大小在0和1024之间且fileName为“springmvc.txt”,必须满足的条件使用+(加号)表示。

 

与BooleanQuery中Occur对应的符号如下:

Occur.MUST 查询条件必须满足,相当于and

+(加号)

Occur.SHOULD 查询条件可选,相当于or

空(不用符号)

Occur.MUST_NOT 查询条件不能满足,相当于not非

-(减号)

 

关键字查询

AND:关键字1  AND 关键字2

两个关键字都匹配上条件满足。

OR:关键字1  OR 关键字2

两个关键字匹配一个条件满足

 

NOT:关键字1  NOT  关键字2

关键字1满足,关键字2不满足

2.3.2 MultiFieldQueryParser组合域查询

通过MuliFieldQueryParse对多个域查询,比如商品信息查询,输入关键字需要从商品名称和商品内容中查询。

代码:

//设置组合查询域String[] fields = {"fileName","fileContent"};//创建查询解析器QueryParser queryParser =  new MultiFieldQueryParser(fields, new IKAnalyzer());//查询文件名、文件内容中包括“java”关键字的文档Query query = queryParser.parse("java");

相关度排序

3.1什么是相关度排序

相关度排序是查询结果按照与查询关键字的相关性进行排序,越相关的越靠前。比如搜索“Lucene”关键字,与该关键字最相关的文章应该排在前边。

3.2 相关度打分

Lucene对查询关键字和索引文档的相关度进行打分,得分高的就排在前边。如何打分呢?Lucene是在用户进行检索时实时根据搜索的关键字计算出来的,分两步:

1)计算出词(Term)的权重

2)根据词的权重值,采用空间向量模型算法计算文档相关度得分。

什么是词的权重?

通过索引部分的学习明确索引的最小单位是一个Term(索引词典中的一个词),搜索也是要从Term中搜索,再根据Term找到文档,Term对文档的重要性称为权重,影响Term权重有两个因素:

Term Frequency (tf):

指此Term在此文档中出现了多少次。tf 越大说明越重要。

词(Term)在文档中出现的次数越多,说明此词(Term)对该文档越重要,如“Lucene”这个词,在文档中出现的次数很多,说明该文档主要就是讲Lucene技术的。

Document Frequency (df)

即有多少文档包含次Term。df 越大说明越不重要。

比如,在一篇英语文档中,this出现的次数更多,就说明越重要吗?不是的,有越多的文档包含此词(Term), 说明此词(Term)太普通,不足以区分这些文档,因而重要性越低。

3.3 设置boost影响打分结果

boost是一个加权值(默认加权值为1.0f),它可以影响权重的计算。

在索引时对某个文档的Field域设置加权值高,在搜索时匹配到这个Field就可能排在前边。

lucene在执行搜索时对某个域进行加权,在进行组合域查询时,匹配到加权值高的域最后计算的相关度得分就高。

3.3.1 索引时设置boost加权值

如果希望某些文档更重要,当此文档中包含所要查询的词则应该得分较高,这样相关度排序可以排在前边,可以在创建索引时设定文档中某些域(Field)的boost值来实现,如果不进行设定,则Field Boost默认为1.0f。一旦设定,除非删除此文档,否则无法改变。

代码:

field. setBoost(XXXf); XXX即权值。

测试:

可以将springmvc.txt的file_content加权值设置为10.0f,结果搜索spring时如果内容可以匹配到关键字就可以把springmvc.txt文件排在前边。

代码:

索引时设置boost加权值:

//设置加权值if(file_name.equals("springmvc.txt")){//设置比默认值 1.0大的field_file_content.setBoost(20.0f);}if(file_name.equals("spring_README.txt")){//设置比默认值 1.0大的field_file_content.setBoost(30.0f);}//向文档中添加Fielddocument.add(field_file_content);

搜索时:

// 设置组合查询域,如果匹配到一个域就返回记录String[] fields = { "file_content" };//设置评分,文件名称中包括关键字的评分高/*Map<String,Float> boosts = new HashMap<String,Float>();boosts.put("file_content", 3.0f);*/// 创建查询解析器QueryParser queryParser = new MultiFieldQueryParser(fields,new StandardAnalyzer());// 查询文件名、文件内容中包括“java”关键字的文档Query query = queryParser.parse("spring");TopDocs topDocs = indexSearcher.search(query, 100);ScoreDoc[] scoreDocs = topDocs.scoreDocs;

结果:

springmvc.txt排在最前边

3.3.2 搜索时设置boost加权值

在执行搜索时对某个域进行加权,在进行组合域查询时,匹配到加权值高的域最后计算的相关度得分就高。通常把标题、书名等域的加权值设置高点。

//设置组合查询域String[] fields = {"file_name","file_content"};//设置评分,文件名称中包括关键字的评分高Map<String,Float> boosts = new HashMap<String,Float>();boosts.put("file_name", 10.0f);//创建查询解析器QueryParser queryParser =  new MultiFieldQueryParser(fields, new IKAnalyzer(), boosts);//查询文件名、文件内容中包括“springmvc.txt”关键字的文档,由于设置了文件名称域的加权值高,所以名称中匹配到关键字的应该排在前边Query query = queryParser.parse("springmvc.txt");

测试:

搜索springmvc.txt,由于文件名中为springmvc.txt应该让它排在前边,内容中有springmvc.txt应该排在后边。

springmvc.txt:

测试结果它应该排在前边

spring_README.txt

内容中包括springmvc.txt,也能匹配到但要排在后边。

代码:

//设置评分,文件名称中包括关键字的评分高Map<String,Float> boosts = new HashMap<String,Float>();boosts.put("file_name", 30.0f);// 创建查询解析器QueryParser queryParser = new MultiFieldQueryParser(fields,new StandardAnalyzer(),boosts);// 查询文件名、文件内容中包括“java”关键字的文档Query query = queryParser.parse("springmvc.txt");TopDocs topDocs = indexSearcher.search(query, 100);ScoreDoc[] scoreDocs = topDocs.scoreDocs;

这篇关于Lucene教程--维护索引、查询对象和相关度排序的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/495976

相关文章

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

Makefile简明使用教程

文章目录 规则makefile文件的基本语法:加在命令前的特殊符号:.PHONY伪目标: Makefilev1 直观写法v2 加上中间过程v3 伪目标v4 变量 make 选项-f-n-C Make 是一种流行的构建工具,常用于将源代码转换成可执行文件或者其他形式的输出文件(如库文件、文档等)。Make 可以自动化地执行编译、链接等一系列操作。 规则 makefile文件

性能分析之MySQL索引实战案例

文章目录 一、前言二、准备三、MySQL索引优化四、MySQL 索引知识回顾五、总结 一、前言 在上一讲性能工具之 JProfiler 简单登录案例分析实战中已经发现SQL没有建立索引问题,本文将一起从代码层去分析为什么没有建立索引? 开源ERP项目地址:https://gitee.com/jishenghua/JSH_ERP 二、准备 打开IDEA找到登录请求资源路径位置

【数据结构】——原来排序算法搞懂这些就行,轻松拿捏

前言:快速排序的实现最重要的是找基准值,下面让我们来了解如何实现找基准值 基准值的注释:在快排的过程中,每一次我们要取一个元素作为枢纽值,以这个数字来将序列划分为两部分。 在此我们采用三数取中法,也就是取左端、中间、右端三个数,然后进行排序,将中间数作为枢纽值。 快速排序实现主框架: //快速排序 void QuickSort(int* arr, int left, int rig

活用c4d官方开发文档查询代码

当你问AI助手比如豆包,如何用python禁止掉xpresso标签时候,它会提示到 这时候要用到两个东西。https://developers.maxon.net/论坛搜索和开发文档 比如这里我就在官方找到正确的id描述 然后我就把参数标签换过来

usaco 1.3 Mixing Milk (结构体排序 qsort) and hdu 2020(sort)

到了这题学会了结构体排序 于是回去修改了 1.2 milking cows 的算法~ 结构体排序核心: 1.结构体定义 struct Milk{int price;int milks;}milk[5000]; 2.自定义的比较函数,若返回值为正,qsort 函数判定a>b ;为负,a<b;为0,a==b; int milkcmp(const void *va,c

hdu 1285(拓扑排序)

题意: 给各个队间的胜负关系,让排名次,名词相同按从小到大排。 解析: 拓扑排序是应用于有向无回路图(Direct Acyclic Graph,简称DAG)上的一种排序方式,对一个有向无回路图进行拓扑排序后,所有的顶点形成一个序列,对所有边(u,v),满足u 在v 的前面。该序列说明了顶点表示的事件或状态发生的整体顺序。比较经典的是在工程活动上,某些工程完成后,另一些工程才能继续,此时

SWAP作物生长模型安装教程、数据制备、敏感性分析、气候变化影响、R模型敏感性分析与贝叶斯优化、Fortran源代码分析、气候数据降尺度与变化影响分析

查看原文>>>全流程SWAP农业模型数据制备、敏感性分析及气候变化影响实践技术应用 SWAP模型是由荷兰瓦赫宁根大学开发的先进农作物模型,它综合考虑了土壤-水分-大气以及植被间的相互作用;是一种描述作物生长过程的一种机理性作物生长模型。它不但运用Richard方程,使其能够精确的模拟土壤中水分的运动,而且耦合了WOFOST作物模型使作物的生长描述更为科学。 本文让更多的科研人员和农业工作者

《数据结构(C语言版)第二版》第八章-排序(8.3-交换排序、8.4-选择排序)

8.3 交换排序 8.3.1 冒泡排序 【算法特点】 (1) 稳定排序。 (2) 可用于链式存储结构。 (3) 移动记录次数较多,算法平均时间性能比直接插入排序差。当初始记录无序,n较大时, 此算法不宜采用。 #include <stdio.h>#include <stdlib.h>#define MAXSIZE 26typedef int KeyType;typedef char In

ural 1026. Questions and Answers 查询

1026. Questions and Answers Time limit: 2.0 second Memory limit: 64 MB Background The database of the Pentagon contains a top-secret information. We don’t know what the information is — you