全文检索功能(Lucene)

全文检索功能(Lucene)Lucene 是一个基于 java 开发全文检索工具包 提供了查询引擎和索引引擎如何实现全文检索 可以使用 Lucene 实现全文检索

大家好,欢迎来到IT知识分享网。

Lucene:全文检索技术

概念:先创建索引,然后再对索引搜索的过程就是全文检索技术;

索引一次创建多次使用,表现为每次的查询速度很快。

索引:一个为了提高查询速度,创建某种数据结构的集合。

  • 数据的分类:
    • 结构化数据:格式、长度、数据类型固定
      • 例如数据库的数据,
    • 非结构化数据:格式、长度、数据类型不固定
      • word文档、pdf文档等等
  • 数据的查询
    • 结构化数据的查询:sql语句
      • 简单、查询速度快
    • 非结构化数据:查询某个关键字?
      • 条件复杂,查询难度大
        • 顺序扫描法
        • 字符串匹配(顺序扫描)
        • 使非结构化的数据变为结构化的数据便于查询
全文检索的应用场景
  • 搜索引擎
    • :百度、谷歌、搜索等等
  • 站内搜索
    • 论坛搜索,微博搜索,文章搜索
  • 电商搜索
    • jd,tb搜索
什么是Lucene:

Lucene是一个基于java开发全文检索工具包,提供了查询引擎和索引引擎

如何实现全文检索:

可以使用Lucene实现全文检索。Lucene是apache下的一个开放源代码的全文检索引擎工具包。提供了完整的查询引擎和索引引擎,部分文本分析引擎。Lucene的目的是为软件开发人员提供一个简单易用的工具包,以方便的在目标系统中实现全文检索的功能。

Lucene实现全文检索的流程:

全文检索功能(Lucene)

全文检索功能(Lucene)

全文检索功能(Lucene)

配置开发环境

Lucene官网下载:

​ luck

​ IKAnalyzer

​ 链接:https://pan.baidu.com/s/1cCZktGtdAPV-rv9IRLm3Og

​ 提取码:kisq

​ 最低要jdk1.8

​ java工程和jar包

​ lucene-core

​ lucene-analyzers-common

​ commons-io

​ junit

入门案例:

步骤:

创建索引库

  1. 创建一个Directory对象,指定索引库保存的位置 Directory directory = FS 一般保存在磁盘上
  2. 基于Directory对象,创建一个IndexWriter对象 IndexWriter indexwrite = new IndexWriter(directory ,new IndexWirterConfig());
  3. 读取磁盘上的文件,对应每一个文件一个文档对象
  4. 向文档对象中添加域
  5. 把文档对象写入索引库
  6. 关闭IndexWriter对象
Directory directory = FSDirectory.open(new File("路径").toPath());//设定索引库存放位置 IndexWirter indexwriter = new IndexWirter(directory,new IndexWirterConfig());//索引写入对象,使用此对象来讲文档写入索引库 File dir = new File("路径"); //获取需要创建索引的文件的路径 File[] files = dir.listFiles();//获取此路径下所有的文件 for(File file:files){ //得到文件信息,建立并写入到域对象中去 //文件信息 此处获取的是文件的名字、路径、大小、内容信息 String fileName = file.getName(); String fileSize = FileUtils.sizeof(file); String fileContent = FileUtils.readFileToString(file); String filePath = file.getPath(); //创建域对象 Field fieldName = new TextField("name",fileName,Field.Store.YES); Field fieldPath = new TextField("path",filePath,Field.Store.YES); Field fieldSize = new TextField("size",fileSize,Field.Store.YES); Field fieldContent = new TextField("content",fileContent,Field.Store.YES); Document document = new Document();//创建文件对象 一个文件对应一个文档对象 //向文档对象里面添加域对象 document.add(fieldPath); document.add(fieldSize); document.add(fieldContent); document.add(fieldName); //使用索引写入对象将文档写入索引库 indexWirter.addDocument(document); //释放资源 indexWirter.close(); } 
使用Luke工具查询索引库:

上面使用的是Lucene是7.4.0版本的,若使用Luke工具的版本是和此对应的,就可以打开Lucene创建的索引库,需要注意的是此版本的Luke工具是JKD9编译的。

总的来说就是根据不同版本的Lucene而选择对应的Luke工具的版本,否则将打不开索引库。

当然创建索引库就是为了查询:下面给出查询步骤:

查询索引库

  1. 创建一个Directory对象,指定索引库的位置
  2. 创建一个IndexReader对象
  3. 创建一个IndexSearcher对象构造方法为IndexReader对象
  4. 创建一个Query对象,tremQuery创建,并且设置需要查询的域对象和查询的关键字
  5. 执行查询,得到一个TopDocs对象
  6. 取查询结果的总记录条数
  7. 取文档列表
Directory directory = FSDirectory.open(new File("路径").toPath());//获取到索引库的位置 IndexReader indexreader = DirectorReader.open(dirctor);//基于directory创建一个索引读取对象 IndexSeacher indexreacher = new IndexSeacher(indexreader);//基于索引读取对象获取索引查询对象 Query query = new TremQuery(new Term("title","Lucene"));//创建查询对象query,Query是一个抽象类,需要他的视线类TremQuery创建 TopDocs topdocs = indexSearcher.search(query,10);//使用indexSearcher对象进行查询,并且设置每次查询的数量 System.out.println("总记录数"+topdcs.totalHits(););//获取击中的所有数量总和 ScopeDoc[] ScopeDoc = topDocs.scoreDocs;//使用此方法scoreDocs可以获取到文档列表是一个数组,然后对数组进行查询 for(ScopeDoc doc:ScopeDoc){ int DocID = doc.doc; Doucment document = indexSearcher.doc(docId);//获取文档ID System.out.println(document.get("name")); System.out.println(document.get("path")); System.out.println(document.get("content")); System.out.println(document.get("size")); } //释放资源 indexReader.close(); 
分析器的分析过程
标准分析器

​ 默认使用标准分析器StandarAnalyzer 使用标准分析器,会将汉语关键字拆分为一个汉字一个汉字的形式

查看分析器的分析效果

​ 使用Analyzer对象的tokenStream方法返回一个TokenStream对象,此对象中包含了最终的分词结果

​ 步骤:

  1. 创建一个Analyzer对象,StandarAnalyzer对象
  2. 使用分析器对象的tokenStream方法获取TokenStream对象
  3. 向TokenStream对象设置一个引用,相当于一个指针
  4. 调用TokenStream对象的rest方法,如果不调用就抛异常
  5. 循环TokenStream对象
  6. 关闭TokenStream对象
Analyzer analyzer = new StandarAnalyzer();//使用一个标准分析器 TokenStream tokenstream = analyzer.tokenStream("xxxxx");// CharTermAttribute charTermAttribute = tokenstream.addAttribute(CharTermAttribute.Class); tokenstream.reset(); while(tokenstream.incrementToken()){ sout(charTermAttribute.ToString()); } tokenStream.close(); 
中文分析器:
  1. jar包
  2. 配置文件和扩展词典
    1. 扩展词典禁止使用Windows的记事本打开,一定要保证文件的编码格式为utf-8
    2. 扩展词典:添加一点新词
    3. 停用词词典:无意义的词和敏感词汇

代码中使用:换一个IndexConfig的构造方法就行

new IndexWriterConfig(new IKAnalyzer())//使用IkAnalyzer中文分析器 
索引库维护

​ 每一个域的属性:是否索引、是否分析、是否存储

  • 添加文档 :根据不同的数据类型来使用不同的域的类型去操作
//创建IndexWirter对象存入磁盘中并且设置中文解析器 IndexWrirter indexwirter = new IndexWriter(new FSDocument.open(new File("路径")),new IndexWirterCongif(new IKAnalyzer())); //创建文档对象 Document document = new Document(); //文档中加入域对象 document.add(new Field("name","新的",Field.STORE.YES)); indexwriter.addDocument(document); indexwriter.close(); 

删除文档

  • 全部删除
IndexWriter.deleteAll(); IndexWriter.close(); 

查询删除 针对性的删除

IndexWriter.deleteDecutments(new Term("name","apache")); IndexWriter.close(); 

修改文档:原理是先删除后添加

Document document = new Document(); document.add(new Field("name","新的",Field.STORE.YES)); //更新操作 indexwriter.updateDocument(new Field("name","原来的",document)); indexwriter.close(); 
索引库查询
  • 使用Query子类查询

    TermQuery:关键词查询

Directory directory = FSDirectory.open(new File("路径").toPath()); IndexReader indexReader = new Indexreader(directory); IndexSearcher indexSearcher = new IndexReader(indexreader); Query query = new TermQuery(new Term("content","Lucene"));//使用TermQuery查询 TopDocs topDocs = indexSearcher.search(query,10); ScoreDoc[] scoreDocs = topDocs.scorcDocs; int sum = topDocs.titalHits; for(ScoreDoc scoreDoc:scoreDocs){ int DocId = scoreDoc.doc; Document document = new Document();//获取文档对象的ID 根据域名称拿到值 document = insearch.doc(DocId); document.get("content");//获取 ..... } indexSearcher.close(); indexReader.close(); 

RangeQuery:范围查询

Query query = LongPoint.newRangeQuery("size", 0l, 100l);//其他都一样 
QueryPaser:根据查询内容先分词后查询
  • jar包
Directory directory = FSDirectory.open(new File("path").toPath()); IndexReader indexReader = new IndexReader(directory); IndexSearcher indexSearcher = new IndexReacher(indexReader); QueryParser queryParser = new QueryParser(Version.LUCENE_8_7_0,"name",new IkAnalyzer());//Lucene的版本 查询的域 解析器类型 TopDocs topDocs = indexSearcher.search(queryParser,10); ScoreDoc[] scoreDocs = topDocs.scoreDoc; int sum = topDocs.totalHits; for(ScoreDoc scoreDoc:scoreDocs){ Doucument document = indexSearcher.doc(scoreDoc.doc); document.get("content");//获取 ..... } indexSearcher.close(); indexReader.close(); 

 

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/134503.html

(0)
上一篇 2025-07-11 20:33
下一篇 2025-07-11 20:45

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信