全文检索——Lucene

Posted 邵鸿鑫

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了全文检索——Lucene相关的知识,希望对你有一定的参考价值。

简单介绍:

  全文检索是一种将文件中所有文本与检索项匹配的文字资料检索方法。全文检索系统是按照全文检索理论建立起来的用于提供全文检索服务的软件系统。

  像我们平时用的百度谷歌搜索引擎,当我们在输入框输入任意内容后点击搜索,搜索引擎就会把与我们搜索内容相关的内容全部检索到,并按照一定的排序规则呈现给我们。

  

  Lucene是apache软件基金会4 jakarta项目组的一个子项目,是一个开放源代码的全文检索引擎工具包,但它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎,部分文本分析引擎(英文与德文两种西方语言)。Lucene的目的是为软件开发人员提供一个简单易用的工具包,以方便的在目标系统中实现全文检索的功能,或者是以此为基础建立起完整的全文检索引擎。Lucene是一套用于全文检索和搜寻的开源程式库,由Apache软件基金会支持和提供。Lucene提供了一个简单却强大的应用程式接口,能够做全文索引和搜寻。在Java开发环境里Lucene是一个成熟的免费开源工具。就其本身而言,Lucene是当前以及最近几年最受欢迎的免费Java信息检索程序库。我们经常提到信息检索程序库,虽然与搜索引擎有关,但不应该将信息检索程序库与搜索引擎相混淆。

  下面我们就实现一个简单的例子,结合实例给大家讲解Lucene的工作机制。

代码结构:


整个实例的实现思路:

1.创建一个article对象,把该对象放到索引库中

1、创建一个article对象
2、把article对象转化成document对象
3、创建一个IndexWriter对象
4、把document对象加入到索引库中

 2.从索引库中把article对象检索出来

   1、创建一个IndexSearch对象

2、创建一个QueryParser对象

3、将document对象转换为article对象

代码:

package com.tgb.lucene.bean;

public class Article 
	private Long id;
	private String title;
	private String content;
	public Long getId() 
		return id;
	
	public void setId(Long i) 
		this.id = i;
	
	public String getTitle() 
		return title;
	
	public void setTitle(String title) 
		this.title = title;
	
	public String getContent() 
		return content;
	
	public void setContent(String content) 
		this.content = content;
	
	

package com.tgb.lucene.helloworld;

import java.io.File;
import java.util.ArrayList;
import java.util.Dictionary;
import java.util.List;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.Field.Index;
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.document.Fieldable;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriter.MaxFieldLength;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
import org.junit.Test;

import com.tgb.lucene.bean.Article;
/**
 * 1.创建一个article对象,把该对象放到索引库中
 * 2.从索引库中把article对象检索出来
 * @author hongxin
 *
 */
public class HelloWorld 

	/**
	 * 创建索引
	 */
	@Test
	public void testCreateIndex() throws Exception
		/**
		 * 1、创建一个article对象
		 * 2、把article对象转化成document对象
		 * 3、创建一个IndexWriter对象
		 * 4、把document对象加入到索引库中
		 */
		
		Article article = new Article();
		article.setId(1L);
		article.setTitle("lucene可以做搜索引擎");
		article.setContent("baidu,google都是很好的搜索引擎");
		
		Document document = new Document();
		/**
		 * 第一个参数
		 *    放入到索引库中的name的名称"id"
		 * 第二个参数
		 *    放入到索引库中的value:id的值 
		 * 第三个参数
		 *    Store
		 *       YES  该字段向内容库中存储
		 *       no   该字段不向内容库中存储
		 * 第四个字段
		 *    Index
		 *       no   不向目录库中存储
		 *       NOT_ANALYZED  存储,但是不分词
		 *       ANALYZED      存储,分词
		 */
		Field idField = new Field("id", article.getId().toString(), Store.YES, Index.NOT_ANALYZED);
		Field titleField = new Field("title", article.getTitle(),Store.NO,Index.ANALYZED);
		Field contentField = new Field("content", article.getContent(), Store.YES, Index.ANALYZED);
		
		document.add(idField);
		document.add(titleField);
		document.add(contentField);
		
		//索引库
		Directory directory=FSDirectory.open(new File("./indexDir"));
		//分词器
		Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_30);
		/**
		 * directory指向了索引库的路径  "./indexDir"
		 * analyzer 分词器  把title,content的内容分词后的内容放入到目录中
		 * MaxFieldLength 限制每一个字段往索引库中存放的大小
		 */
		IndexWriter indexWriter = new IndexWriter(directory,analyzer, MaxFieldLength.LIMITED);
		indexWriter.addDocument(document);
		
		indexWriter.commit();
		indexWriter.close();
	
	
	/*
	 * 搜索的过程
	 */
	@Test
	public void testSearchIndex() throws Exception
		//索引库
		Directory directory = FSDirectory.open(new File("./indexDir"));
		/**
		 * 创建一个IndexSearch对象
		 */
		IndexSearcher indexSearcher = new IndexSearcher(directory);
		
		Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_30);
		/**
		 * 第一个参数
		 *     版本号
		 * 第二个参数
		 *     在哪个字段中进行检索
		 * 第三个参数
		 *     为分词器,在调用queryParser的parse方法的时候,需要对参数再次进行分词
		 */
		QueryParser queryParser = new QueryParser(Version.LUCENE_30, "title", analyzer);
		Query query = queryParser.parse("lucene");
		/**
		 * query参数
		 *     包含了一个分词器
		 *     包含了一个关键词
		 * n 查找前n条记录
		 * TopDocs==Top Documents  前一些Documents
		 */
		TopDocs topDocs = indexSearcher.search(query, 1);
		int count = topDocs.totalHits;  // 根据关键词计算出来的总的记录数
		//ScoreDoc= Score  Document
		ScoreDoc[] scoreDocs = topDocs.scoreDocs;
		List<Article> articles = new ArrayList<Article>();
		for (ScoreDoc scoreDoc : scoreDocs) 
			float score = scoreDoc.score;//相关度得分
			//scoreDoc.doc  根据关键词找到的索引
			Document document = indexSearcher.doc(scoreDoc.doc);
			//Document转化成article的过程
			Article article = new Article();
			article.setId(Long.parseLong(document.get("id")));
			article.setTitle(document.get("title"));
			article.setContent(document.get("content"));
			articles.add(article);
		
		
		for (Article article : articles) 
			System.out.println(article.getId());
			System.out.println(article.getTitle());
			System.out.println(article.getContent());
		
	




以上是关于全文检索——Lucene的主要内容,如果未能解决你的问题,请参考以下文章

Lucene基本都是概念的东西,希望等我自己回头看的时候还能记起来点就行

Lucene学习

Elasticsearch7从入门到精通(简介部署原理开发ELK)

全文搜索服务器solr

Lucene的全文检索学习

Lucene全文检索