欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

lucene教程

程序员文章站 2022-05-21 19:58:12
...

luence是一个非常好的检索工具,,使用简单,几行代码就能搞定。

Lucene的架构设计及介绍

lucene教程

 这个架构分为两部分,一是建立索引,从数据源建立相应的索引机制,二是索引查询,输入关键词,根据索引,查找并且返回结果。

1.lucene包

org.apache.Lucene.search/ 搜索入口
org.apache.Lucene.index/ 索引入口
org.apache.Lucene.analysis/ 语言分析器
org.apache.Lucene.queryParser/ 查询分析器
org.apache.Lucene.document/ 存储结构
org.apache.Lucene.store/  底层IO/存储结构
org.apache.Lucene.util/ 一些公用的数据结构

2.索引过程的核心类

·IndexWriter
·Directory
·Analyzer
·Document
·Field

①IndexWriter
索引过程的核心组件。这个类负责创建新索引或者打开已有索引,以及向索引中添加、删除或更新被索引文档的信息。可以把IndexWriter看作这样一个对象:它为你提供针对索引文件的写入操作,但不能用于读取或搜索索引。IndexWriter需要开辟一定空间来存储索引,该功能可以由Directory完成。

②Directory
该类描述了Lucene索引的存放位置。它是一个抽象类,它的子类负责具体指定索引的存储路径。用FSDirectory.open方法来获取真实文件在文件系统的存储路径,然后将它们一次传递给IndexWriter类构造方法。IndexWriter不能直接索引文本,这需要先由Analyzer将文本分割成独立的单词才行。

③Analyzer
文本文件在被索引之前,需要经过Analyzer(分析器)处理。Analyzer是由IndexWriter的构造方法来指定的,它负责从被索引文本文件中提取语汇单元,并提出剩下的无用信息。如果被索引内容不是纯文本文件,那就需要先将其转换为文本文档。对于要将Lucene集成到应用程序的开发人员来说,选择什么样Analyzer是程序设计中非常关键的一步。分析器的分析对象为文档,该文档包含一些分离的能被索引的域。

④Document
Document对象代表一些域(Field)的集合。文档的域代表文档或者文档相关的一些元数据。元数据(如作者、标题、主题和修改日期等)都作为文档的不同域单独存储并被索引。Document对象的结构比较简单,为一个包含多个Filed对象容器;Field是指包含能被索引的文本内容的类。

⑤Field
索引中的每个文档都包含一个或多个不同命名的域,这些域包含在Field类中。每个域都有一个域名和对应的域值,以及一组选项来精确控制Lucene索引操作各个域值。

3.搜索过程中的核心类

 IndexSearcher
·Term
·Query
·TermQuery
·TopDocs


①IndexSearcher
该类用于搜索由IndexWriter类创建的索引,它是连接索引的中心环节。可以将IndexSearcher类看作是一个以只读方式打开索引的类。它需要利用Directory实例来掌控前期创建的索引,然后才能提供大量的搜索方法。
②Term
Term对象是搜索功能的基本单元。Term对象包含一对字符串元素:域名和单词(或域名文本值)。
③Query
包含了一些非常有用的方法,TermQuery是它的一个子类。
④TermQuery
该类提供最基本的查询,用来匹配指定域中包含特定项的文档。
⑤TopDocs
该类是一个简单的指针容器,指针一般指向前N个排名的搜索结果,搜索结果即匹配查询条件的文档。

建立索引

首先 我在桌面建立数据源

 

 

lucene教程

 其次 我把索引目录放在 C:\Users\Administrator\Desktop\xxxx上

 

加入maven包

              <dependency>
			<groupId>org.apache.lucene</groupId>
			<artifactId>lucene-core</artifactId>
			<version>4.0.0</version>
		</dependency>
		<dependency>
			<groupId>org.apache.lucene</groupId>
			<artifactId>lucene-queryparser</artifactId>
			<version>4.0.0</version>
		</dependency>
		<dependency>
			<groupId>org.apache.lucene</groupId>
			<artifactId>lucene-analyzers-common</artifactId>
			<version>4.0.0</version>
		</dependency>
		<dependency>
			<groupId>org.apache.lucene</groupId>
			<artifactId>lucene-highlighter</artifactId>
			<version>4.0.0</version>
		</dependency>

完整的代码实现

 

	Directory directory = FSDirectory.open(new File("C:\\Users\\Administrator\\Desktop\\xxxx"));
		File sourceDirectory = new File("C:\\Users\\Administrator\\Desktop\\yyyy");
		IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_CURRENT, analyzer);
		IndexWriter iwriter = new IndexWriter(directory, config);

		for (int i = 0; i < sourceDirectory.listFiles().length; i++) {
			Document doc = new Document();
			File fi = sourceDirectory.listFiles()[i];
			
			//基于Reader实现
			Reader txtReader = new FileReader(sourceDirectory.listFiles()[i]);
			doc.add(new TextField("content1", txtReader));
            
			BufferedReader reader = new BufferedReader(new FileReader(fi));
			String temp = null;
			StringBuffer sb = new StringBuffer();
			while ((temp = reader.readLine()) != null) {
				sb.append(temp);
			}
			reader.close();
			String context = sb.toString();
			System.out.print(context);
			doc.add(new TextField("content2", context, Store.YES));

			doc.add(new TextField("path", fi.getAbsolutePath(), Store.YES));
			iwriter.addDocument(doc);
		}
		iwriter.close();

查询

    Directory directory = FSDirectory.open( new File("C:\\Users\\Administrator\\Desktop\\xxxx"));
	    String text = "hello";
	    DirectoryReader ireader = DirectoryReader.open(directory);
	    IndexSearcher isearcher = new IndexSearcher(ireader);
	    Term term = new Term("content2", text.toLowerCase());
	    TermQuery termQuery = new TermQuery(term);
	  
	
        QueryScorer scorer = new QueryScorer(termQuery);
        SimpleHTMLFormatter simpleHtmlFormatter = new SimpleHTMLFormatter("<B>","</B>");//设定高亮显示的格式<B>keyword</B>,此为默认的格式  
        Highlighter highlighter = new Highlighter(simpleHtmlFormatter,scorer);   
        highlighter.setTextFragmenter(new SimpleFragmenter(20));//设置每次返回的字符数
        ScoreDoc[] hits = isearcher.search(termQuery,10000).scoreDocs;
        Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_CURRENT);
	    for (int i = 0; i < hits.length; i++) {
	      Document hitDoc = isearcher.doc(hits[i].doc);
	      System.out.print(hitDoc.get("content1")+"\n");
	      System.out.print(hitDoc.get("content2")+"\n");
	      System.out.print(hitDoc.get("path")+"\n");
          String str = highlighter.getBestFragment(analyzer, "content2", hitDoc.get("content2")) ;
          System.out.println(str);   
	    }
	    ireader.close();
	    directory.close();

运行结果

C:\Users\Administrator\Desktop\yyyy\bb.txt
<B>Hello</B> world��Do say
C:\Users\Administrator\Desktop\yyyy\cc.txt
<B>Hello</B> world��Do say
C:\Users\Administrator\Desktop\yyyy\aa.txt
<B>Hello</B> world��Do say

 

参考文档

 http://lucene.apache.org/core/4_0_0/core/overview-summary.html

https://www.chedong.com/tech/lucene.html#intro