lucence 全文搜索

2023-11-12 00:30
文章标签 搜索 全文 lucence

本文主要是介绍lucence 全文搜索,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

什么是全文搜索?

数据的分类

  • 结构化数据:指具有固定格式或有限长度的数据,如数据库,元数据等。
  • 非结构化数据:指不定长或无固定格式的数据,如邮件,word文档等磁盘上的文件
    查询方法:
    顺序扫描:从头看到尾,如果此文档包含此字符串,则此文档为我们要找的文,接着看下一个文件,直到扫描完所有的文件。如利用windows的搜索也可以搜索文件内容,只是相当的慢。
    全文检索:将非结构化数据中的一部分信息提取出来,重新组织,使其变得有一定结构,然后对此有一定结构的数据进行搜索,从而达到搜索相对较快的目的。这部分从非结构化数据中提取出的然后重新组织的信息,我们称之索引
    例如:字典。字典的拼音表和部首检字表就相当于字典的索引,对每一个字的解释是非结构化的,如果字典没有音节表和部首检字表,在茫茫辞海中找一个字只能顺序扫描。然而字的某些信息可以提取出来进行结构化处理,比如读音,就比较结构化,分声母和韵母,分别只有几种可以一一列举,于是将读音拿出来按一定的顺序排列,每一项读音都指向此字的详细解释的页数。我们搜索时按结构化的拼音搜到读音,然后按其指向的页数,便可找到我们的非结构化数据——也即对字的解释。
    这种先建立索引,再对索引进行搜索的过程就叫全文检索(Full-text Search)。
    虽然创建索引的过程也是非常耗时的,但是索引一旦创建就可以多次使用,全文检索主要处理的是查询,所以耗时间创建索引是值得的。
    应用场景:对于数据量大、数据结构不固定的数据可采用全文检索方式搜索,比如百度、Google等搜索引擎、论坛站内搜索、电商网站站内搜索等。

Lucene实现全文检索

在这里插入图片描述
1、绿色表示索引过程,对要搜索的原始内容进行索引构建一个索引库,索引过程包括:
确定原始内容即要搜索的内容—》采集文档----》创建文档----》分析文档—》索引文档

2、红色表示搜索过程,从索引库中搜索内容,搜索过程包括:
用户通过搜索界面—》创建查询—》执行搜索,从索引库搜索—》渲染搜索结果

配置开发环境

lucence下载

Lucene是开发全文检索功能的工具包,从官方网站下载Lucene4.10.3,并解压。
官方网站:http://lucene.apache.org/
jar包
在这里插入图片描述
在这里插入图片描述
其它:
commons-io-2.4.jar
junit-4.9.jar

入门小程序

实现一个文件的搜索功能,通过关键字搜索文件,凡是文件名或文件内容包括关键字的文件都需要找出来。还可以根据中文词语进行查询,并且需要支持多个条件查询。

创建索引

(0)创建一个java工程,导入上面的四个jar包
(1)指定索引库存放的路径
(2)创建indexwriter对象
a.指定索引库的存放位置
b.指定一个分析器,对文档内容进行分析
(3)创建docunment对象
(4)创建field对象,将filed添加到document对象中
(5)使用indexwriter对象将document对象写入索引库,此过程进行索引创建。并将索引和document对象写入索引库。
(6)关闭IndexWriter对象。

//创建索引@Testpublic void createIndex() throws Exception {//指定索引库存放的路径//D:\temp\0108\indexDirectory directory = FSDirectory.open(new File("D:\\temp\\0108\\index"));//索引库还可以存放到内存中//Directory directory = new RAMDirectory();//创建一个标准分析器Analyzer analyzer = new StandardAnalyzer();//创建indexwriterCofig对象//第一个参数: Lucene的版本信息,可以选择对应的lucene版本也可以使用LATEST//第二根参数:分析器对象IndexWriterConfig config = new IndexWriterConfig(Version.LATEST, analyzer);//创建indexwriter对象IndexWriter indexWriter = new IndexWriter(directory, config);//原始文档的路径D:\传智播客\01.课程\04.lucene\01.参考资料\searchsourceFile dir = new File("D:\\传智播客\\01.课程\\04.lucene\\01.参考资料\\searchsource");for (File f : dir.listFiles()) {//文件名String fileName = f.getName();//文件内容String fileContent = FileUtils.readFileToString(f);//文件路径String filePath = f.getPath();//文件的大小long fileSize  = FileUtils.sizeOf(f);//创建文件名域//第一个参数:域的名称//第二个参数:域的内容//第三个参数:是否存储Field fileNameField = new TextField("filename", fileName, Store.YES);//文件内容域Field fileContentField = new TextField("content", fileContent, Store.YES);//文件路径域(不分析、不索引、只存储)Field filePathField = new TextField("path", filePath);//文件大小域Field fileSizeField = new TextField("size", fileSize + "", Store.YES);//创建document对象Document document = new Document();document.add(fileNameField);document.add(fileContentField);document.add(filePathField);document.add(fileSizeField);//创建索引,并写入索引库indexWriter.addDocument(document);}//关闭indexwriterindexWriter.close();}

查询索引

第一步:创建一个Directory对象,也就是索引库存放的位置。
第二步:创建一个indexReader对象,需要指定Directory对象。
第三步:创建一个indexsearcher对象,需要指定IndexReader对象
第四步:创建一个TermQuery对象,指定查询的域和查询的关键词。
第五步:执行查询。
第六步:返回查询结果。遍历查询结果并输出。
第七步:关闭IndexReader对象

//查询索引库@Testpublic void searchIndex() throws Exception {//指定索引库存放的路径//D:\temp\0108\indexDirectory directory = FSDirectory.open(new File("D:\\temp\\0108\\index"));//创建indexReader对象IndexReader indexReader = DirectoryReader.open(directory);//创建indexsearcher对象IndexSearcher indexSearcher = new IndexSearcher(indexReader);//创建查询Query query = new TermQuery(new Term("filename", "apache"));//执行查询//第一个参数是查询对象,第二个参数是查询结果返回的最大值TopDocs topDocs = indexSearcher.search(query, 10);//查询结果的总条数System.out.println("查询结果的总条数:"+ topDocs.totalHits);//遍历查询结果//topDocs.scoreDocs存储了document对象的idfor (ScoreDoc scoreDoc : topDocs.scoreDocs) {//scoreDoc.doc属性就是document对象的id//根据document的id找到document对象Document document = indexSearcher.doc(scoreDoc.doc);System.out.println(document.get("filename"));//System.out.println(document.get("content"));System.out.println(document.get("path"));System.out.println(document.get("size"));}//关闭indexreader对象indexReader.close();}

分词器

//查看标准分析器的分词效果public void testTokenStream() throws Exception {//创建一个标准分析器对象Analyzer analyzer = new StandardAnalyzer();//获得tokenStream对象//第一个参数:域名,可以随便给一个//第二个参数:要分析的文本内容TokenStream tokenStream = analyzer.tokenStream("test", "The Spring Framework provides a comprehensive programming and configuration model.");//添加一个引用,可以获得每个关键词CharTermAttribute charTermAttribute = tokenStream.addAttribute(CharTermAttribute.class);//将指针调整到列表的头部tokenStream.reset();//遍历关键词列表,通过incrementToken方法判断列表是否结束while(tokenStream.incrementToken()) {//取关键词System.out.println(charTermAttribute);}tokenStream.close();}

Analyzer 每个分词器tokenStream方法
// Analyzer analyzer = new StandardAnalyzer(); //英文按照空格分词,中文一个字一个字
// Analyzer analyzer = new CJKAnalyzer(); //中文两个字两个字
// 需要导入lucene-analyzers-smartcn-4.10.3.jar
// Analyzer analyzer = new SmartChineseAnalyzer(); //中文还可以,但是英文容易出现缺字母

// 第三方分词器IK-Analyzer
// 需要导入jar IKAnalyzer2012FF_u1.jar
Analyzer analyzer = new IKAnalyzer();

这篇关于lucence 全文搜索的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

C# ComboBox下拉框实现搜索方式

《C#ComboBox下拉框实现搜索方式》文章介绍了如何在加载窗口时实现一个功能,并在ComboBox下拉框中添加键盘事件以实现搜索功能,由于数据不方便公开,作者表示理解并希望得到大家的指教... 目录C# ComboBox下拉框实现搜索步骤一步骤二步骤三总结C# ComboBox下拉框实现搜索步骤一这

认识、理解、分类——acm之搜索

普通搜索方法有两种:1、广度优先搜索;2、深度优先搜索; 更多搜索方法: 3、双向广度优先搜索; 4、启发式搜索(包括A*算法等); 搜索通常会用到的知识点:状态压缩(位压缩,利用hash思想压缩)。

hdu1240、hdu1253(三维搜索题)

1、从后往前输入,(x,y,z); 2、从下往上输入,(y , z, x); 3、从左往右输入,(z,x,y); hdu1240代码如下: #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#inc

hdu 4517 floyd+记忆化搜索

题意: 有n(100)个景点,m(1000)条路,时间限制为t(300),起点s,终点e。 访问每个景点需要时间cost_i,每个景点的访问价值为value_i。 点与点之间行走需要花费的时间为g[ i ] [ j ] 。注意点间可能有多条边。 走到一个点时可以选择访问或者不访问,并且当前点的访问价值应该严格大于前一个访问的点。 现在求,从起点出发,到达终点,在时间限制内,能得到的最大

AI基础 L9 Local Search II 局部搜索

Local Beam search 对于当前的所有k个状态,生成它们的所有可能后继状态。 检查生成的后继状态中是否有任何状态是解决方案。 如果所有后继状态都不是解决方案,则从所有后继状态中选择k个最佳状态。 当达到预设的迭代次数或满足某个终止条件时,算法停止。 — Choose k successors randomly, biased towards good ones — Close

hdu4277搜索

给你n个有长度的线段,问如果用上所有的线段来拼1个三角形,最多能拼出多少种不同的? import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;

浙大数据结构:04-树7 二叉搜索树的操作集

这道题答案都在PPT上,所以先学会再写的话并不难。 1、BinTree Insert( BinTree BST, ElementType X ) 递归实现,小就进左子树,大就进右子树。 为空就新建结点插入。 BinTree Insert( BinTree BST, ElementType X ){if(!BST){BST=(BinTree)malloc(sizeof(struct TNo

速通GPT-3:Language Models are Few-Shot Learners全文解读

文章目录 论文实验总览1. 任务设置与测试策略2. 任务类别3. 关键实验结果4. 数据污染与实验局限性5. 总结与贡献 Abstract1. 概括2. 具体分析3. 摘要全文翻译4. 为什么不需要梯度更新或微调⭐ Introduction1. 概括2. 具体分析3. 进一步分析 Approach1. 概括2. 具体分析3. 进一步分析 Results1. 概括2. 具体分析2.1 语言模型

【python计算机视觉编程——7.图像搜索】

python计算机视觉编程——7.图像搜索 7.图像搜索7.1 基于内容的图像检索(CBIR)从文本挖掘中获取灵感——矢量空间模型(BOW表示模型)7.2 视觉单词**思想****特征提取**: 创建词汇7.3 图像索引7.3.1 建立数据库7.3.2 添加图像 7.4 在数据库中搜索图像7.4.1 利用索引获取获选图像7.4.2 用一幅图像进行查询7.4.3 确定对比基准并绘制结果 7.

记忆化搜索【下】

375. 猜数字大小II 题目分析 题目链接:375. 猜数字大小 II - 力扣(LeetCode) 题目比较长,大致意思就是给一个数,比如说10,定的数字是7,让我们在[1, 10]这个区间猜。 如果猜大或猜小都会说明是大了还是小了,此外,我们还需要支付猜错数字对应的现金。 现在就是让我们定制一个猜测策略,确保准备最少的钱能猜对 如果采用二分查找,只能确保最小次数,题目要求的