全文检索工具包 - Lucene

全文检索是什么?

全文搜索引擎:以下统称为全文检索
  全文检索概念:从全文数据中进行检索就叫全文检索,是基于文本的搜索。
  Apache Lucene是一个用Java写的高性能、可伸缩的全文检索引擎工具包,它可以方便的嵌入到各种应用中实现针对应用的全文索引/检索功能。Lucene的目标是为各种中小型应用程序加入全文检索功能。
  现在比较流行的比较多的就是EltaticSearch[简称ES] ,它也是基于lucene扩展的全文检索工具

现实案例

  1. windows系统中的有搜索功能
    在这里插入图片描述2) 各大网站搜索引擎
    在这里插入图片描述
    了解一下:
    结构化数据和非结构化数据
  • 1.结构化数据:指具有“固定格式”或者“有限长度” 的数据,例如数据库 ,元数据等。
  • 2.非结构化数据:指不定长或无固定格式的数据,例如邮箱,word文档。
  • 3.半结构化数据:如xml,html等,当根据需要可按结构化数据来处理,也可抽取出纯文本按非结构化数据来处理。

我们为什么要用全文检索?

对以上几种案例从搜索类型,搜索范围,搜索速度进行分析。

常见搜索搜索类型搜索范围搜索速度
Windows资源管理器文件搜索电脑上面文件很慢
Eclipse帮助文档搜索全文索引搜索帮助文档
数据库搜索数据库搜索数据库表
互联网搜索全文索引搜索互联网资源很快

综上所述:
  对一个非结构化的文本数据进行搜索效率很低,可以使用全文检索(全文索引搜索),就是使用一定的技术(在这里我们使用lucene)将非结构化的文本转换为有一定的结构,提高文本的检索效率。

不仅如此:全文检索还有以下特点

  • 相关度排序:最高的排在最前面,官网中相关的网页排在最前面;
  • 对摘要进行了截取;
  • 关键词的高亮。
  • 只关注文本,不考虑语义。

  •   比如在输入框中输入“中国的首都在哪里”,搜索引擎不会以对话的形式告诉你“在北京”,而仅仅是列出包含了搜索关键字的网页。
    在搜索引擎中查询关键词或句子时,你在最后加上问号也是没有意义的做法,会直接被过滤掉。

一般在什么时候使用

1.替换数据库模糊查询,提高查询速度(接触最多)

  • 数据库缺点
    1.查询速度慢
    2.模糊查询搜索效果不佳
    3.没有相关度排序
  • 具体
      关系数据库中进行模糊查询时,数据库自带的全文索引将不起作用,此时需要通过全文检索来提高速度。

2.只对“指定领域”的网站进行索引与搜索(即垂直搜索)
  如“818工作搜索”、“有道购物搜索”
在这里插入图片描述3.在word、pdf等各种各样的数据格式中检索内容

4.其它场合:比如搜狐拼音输入法、Google输入法等

  项目中我们使用Lucene替换数据库中的like模糊查询。Like模糊查询通过explain解释没有使用到索引,会对全表进行逐行的扫描,如果说数据量比较庞大,搜索效率极低,用户体验差并且数据库压力大。
我们使用Lucene替换数据库的模糊查询,提高查询速度,增强用户体验,降低数据库的压力。

底层原理:[创建索引],[根据索引查询]

在这里插入图片描述
在这里插入图片描述

- 创建索引

步骤:

  • 1 把文本内容转换为Document对象文本是作为Document对象的一个字段而存在
  • 2 准备IndexWriter(索引写入器)
  • 3 通过IndexWriter,把Document添加到缓冲区并提交
    addDocument();
    commit();
    close();
//创建索引的数据 现在写死,以后根据实际应用场景
	String doc1 = "hello world";
	String doc2 = "hello java world";
	String doc3 = "hello lucene world";
	private String path ="F:/eclipse/workspace/lucene/index/
            hello";
@Test
	public void testCreate() {
		try {
			//2、准备IndexWriter(索引写入器)
			//索引库的位置 FS fileSystem
			Directory d = FSDirectory.open(Paths.get(path ));
			//分词器
			Analyzer analyzer = new SimpleAnalyzer();
			//索引写入器的配置对象
			IndexWriterConfig conf = new IndexWriterConfig(analyzer);
			IndexWriter indexWriter = new IndexWriter(d, conf);
			System.out.println(indexWriter);
			
			//1、 把文本内容转换为Document对象
			//把文本转换为document对象
			Document document1 = new Document();
			//标题字段
			document1.add(new TextField("title", "doc1", Store.YES));
			document1.add(new TextField("content", doc1, Store.YES));
			//添加document到缓冲区
			indexWriter.addDocument(document1);
			Document document2 = new Document();
			//标题字段
			document2.add(new TextField("title", "doc2", Store.YES));
			document2.add(new TextField("content", doc2, Store.YES));
			//添加document到缓冲区
			indexWriter.addDocument(document2);
			Document document3 = new Document();
			//标题字段
			document3.add(new TextField("title", "doc3", Store.YES));
			document3.add(new TextField("content", doc3, Store.YES));
			
			//3 、通过IndexWriter,把Document添加到缓冲区并提交
			//添加document到缓冲区
			indexWriter.addDocument(document3);
			indexWriter.commit();
			indexWriter.close();
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	
	}

- 根据索引搜索

步骤

  • 1 封装查询提交为查询对象
  • 2 准备IndexSearcher
  • 3 使用IndexSearcher传入查询对象做查询-----查询出来只是文档编号DocID
  • 4 通过IndexSearcher传入DocID获取文档
  • 5 把文档转换为前台需要的对象 Docment----> Article
@Test
	public void testSearch() {
		String keyWord = "lucene";
		try {
			// * 1 封装查询提交为查询对象
		    //通过查询解析器解析一个字符串为查询对象
			String f = "content"; //查询的默认字段名,
			Analyzer a = new SimpleAnalyzer();//查询关键字要分词,所有需要分词器
			QueryParser parser = new QueryParser(f, a);
			Query query = parser.parse("content:"+keyWord);
			// * 2 准备IndexSearcher
			Directory d = FSDirectory.open(Paths.get(path ));
			IndexReader r = DirectoryReader.open(d);
			IndexSearcher searcher = new IndexSearcher(r);
			// * 3 使用IndexSearcher传入查询对象做查询-----查询出来只是文档编号DocID
			TopDocs topDocs = searcher.search(query, 1000);//查询ton条记录 前多少条记录
			System.out.println("总命中数:"+topDocs.totalHits);
			ScoreDoc[] scoreDocs = topDocs.scoreDocs;//命中的所有的文档的封装(docId)
			// * 4 通过IndexSearcher传入DocID获取文档
			for (ScoreDoc scoreDoc : scoreDocs) {
				int docId = scoreDoc.doc;
				Document document = searcher.doc(docId);
				// * 5 把文档转换为前台需要的对象 Docment----> Article
				System.out.println("=======================================");
				System.out.println("title:"+document.get("title")
								+",content:"+document.get("content"));
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值