Lucene第一篇【介绍Lucene、快速入门】
什么是Lucene??
Lucene是apache软件基金会发布的一个开放源代码的全文检索引擎工具包,由资深全文检索专家Doug Cutting所撰写,它是一个全文检索引擎的架构,提供了完整的创建索引和查询索引,以及部分文本分析的引擎,Lucene的目的是为软件开发人员提供一个简单易用的工具包,以方便在目标系统中实现全文检索的功能,或者是以此为基础建立起完整的全文检索引擎,Lucene在全文检索领域是一个经典的祖先,现在很多检索引擎都是在其基础上创建的,思想是相通的。
Lucene是根据关健字来搜索的文本搜索工具,只能在某个网站内部搜索文本内容,不能跨网站搜索
既然谈到了网站内部的搜索,那么我们就谈谈我们熟悉的百度、google那些搜索引擎又是基于什么搜索的呢….
从图上已经看得很清楚,baidu、google等搜索引擎其实是通过网络爬虫的程序来进行搜索的…
为什么我们要用Lucene?
在介绍Lucene的时候,我们已经说了:Lucene又不是搜索引擎,仅仅是在网站内部进行文本的搜索。那我们为什么要学他呢???
我们之前编写纳税服务系统的时候,其实就已经使用过SQL来进行站内的搜索..
既然SQL能做的功能,我们还要学Lucene,为什么呢???
我们来看看我们用SQL来搜索的话,有什么缺点:
- (1)SQL只能针对数据库表搜索,不能直接针对硬盘上的文本搜索
- (2)SQL没有相关度排名
- (3)SQL搜索结果没有关健字高亮显示
- (4)SQL需要数据库的支持,数据库本身需要内存开销较大,例如:Oracle
- (5)SQL搜索有时较慢,尤其是数据库不在本地时,超慢,例如:Oracle
我们来看看在baidu中搜索Lucene为关键字搜索出的内容是怎么样的:
以上所说的,我们如果使用SQL的话,是做不到的。因此我们就学习Lucene来帮我们在站内根据文本关键字来进行搜索数据!
我们如果网站需要根据关键字来进行搜索,可以使用SQL,也可以使用Lucene…那么我们Lucene和SQL是一样的,都是在持久层中编写代码的。。
快速入门
接下来,我们就讲解怎么使用Lucene了…..在讲解Lucene的API之前,我们首先来讲讲Lucene存放的究竟是什么内容…我们的SQL使用的是数据库中的内存,在硬盘中为DBF文件…那么我们Lucene内部又是什么东西呢??
Lucene中存的就是一系列的二进制压缩文件和一些控制文件,它们位于计算机的硬盘上,
这些内容统称为索引库,索引库有二部份组成:
- (1)原始记录
- 存入到索引库中的原始文本,例如:我是钟福成
- (2)词汇表
- 按照一定的拆分策略(即分词器)将原始记录中的每个字符拆开后,存入一个供将来搜索的表
也就是说:Lucene存放数据的地方我们通常称之为索引库,索引库又分为两部分组成:原始记录和词汇表….
原始记录和词汇表
当我们想要把数据存到索引库的时候,我们首先存入的是将数据存到原始记录上面去….
又由于我们给用户使用的时候,用户使用的是关键字来进行查询我们的具体记录。因此,我们需要把我们原始存进的数据进行拆分!将拆分出来的数据存进词汇表中。
词汇表就是类似于我们在学Oracle中的索引表,拆分的时候会给出对应的索引值。
一旦用户根据关键字来进行搜索,那么程序就先去查询词汇表中有没有该关键字,如果有该关键字就定位到原始记录表中,将符合条件的原始记录返回给用户查看。
我们查看以下的图方便理解:
到了这里,有人可能就会疑问:难道原始记录拆分的数据都是一个一个汉字进行拆分的吗??然后在词汇表中不就有很多的关键字了???
其实,我们在存到原始记录表中的时候,可以指定我们使用哪种算法来将数据拆分,存到词汇表中…..我们的图是Lucene的标准分词算法,一个一个汉字进行拆分。我们可以使用别的分词算法,两个两个拆分或者其他的算法。
编写第一个Lucene程序
首先,我们来导入Lucene的必要开发包:
- lucene-core-3.0.2.jar【Lucene核心】
- lucene-analyzers-3.0.2.jar【分词器】
- lucene-highlighter-3.0.2.jar【Lucene会将搜索出来的字,高亮显示,提示用户】
- lucene-memory-3.0.2.jar【索引库优化策略】
创建User对象,User对象封装了数据….
/**
* Created by ozc on 2017/7/12.
*/
public class User {
private String id ;
private String userName;
private String sal;
public User() {
}
public User(String id, String userName, String sal) {
this.id = id;
this.userName = userName;
this.sal = sal;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getSal() {
return sal;
}
public void setSal(String sal) {
this.sal = sal;
}
}
我们想要使用Lucene来查询出站内的数据,首先我们得要有个索引库吧!于是我们先创建索引库,将我们的数据存到索引库中。
创建索引库的步骤:
- 1)创建JavaBean对象
- 2)创建Docment对象
- 3)将JavaBean对象所有的属性值,均放到Document对象中去,属性名可以和JavaBean相同或不同
- 4)创建IndexWriter对象
- 5)将Document对象通过IndexWriter对象写入索引库中
- 6)关闭IndexWriter对象
@Test
public void createIndexDB() throws Exception {
//把数据填充到JavaBean对象中
User user = new User("1", "钟福成", "未来的程序员");
//创建Document对象【导入的是Lucene包下的Document对象】
Document document = new Document();
//将JavaBean对象所有的属性值,均放到Document对象中去,属性名可以和JavaBean相同或不同
/**
* 向Document对象加入一个字段
* 参数一:字段的关键字
* 参数二:字符的值
* 参数三:是否要存储到原始记录表中
* YES表示是
* NO表示否
* 参数四:是否需要将存储的数据拆分到词汇表中
* ANALYZED表示拆分
* NOT_ANALYZED表示不拆分
*
* */
document.add(new Field("id", user.getId(), Field.Store.YES, Field.Index.ANALYZED));
document.add(new Field("userName", user.getUserName(), Field.Store.YES, Field.Index.ANALYZED));
document.add(new Field("sal", user.getSal(), Field.Store.YES, Field.Index.ANALYZED));
//创建IndexWriter对象
//目录指定为E:/createIndexDB
Directory directory = FSDirectory.open(new File("E:/createIndexDB"));
//使用标准的分词算法对原始记录表进行拆分
Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_30);
//LIMITED默认是1W个
IndexWriter.MaxFieldLength maxFieldLength = IndexWriter.MaxFieldLength.LIMITED;
/**
* IndexWriter将我们的document对象写到硬盘中
*
* 参数一:Directory d,写到硬盘中的目录路径是什么
* 参数二:Analyzer a, 以何种算法来对document中的原始记录表数据进行拆分成词汇表
* 参数三:MaxFieldLength mfl 最多将文本拆分出多少个词汇
*
* */
IndexWriter indexWriter = new IndexWriter(directory, analyzer, maxFieldLength);
//将Document对象通过IndexWriter对象写入索引库中
indexWriter.addDocument(document);
//关闭IndexWriter对象
indexWriter.close();
}
程序执行完,我们就会在硬盘中见到我们的索引库。
那我们现在是不知道记录是否真真正正存储到索引库中的,因为我们看不见。索引库存放的数据放在cfs文件下,我们也是不能打开cfs文件的。
于是,我们现在用一个关键字,把索引库的数据读取。看看读取数据是否成功。
根据关键字查询索引库中的内容:
- 1)创建IndexSearcher对象
- 2)创建QueryParser对象
- 3)创建Query对象来封装关键字
- 4)用IndexSearcher对象去索引库中查询符合条件的前100条记录,不足100条记录的以实际为准
- 5)获取符合条件的编号
- 6)用indexSearcher对象去索引库中查询编号对应的Document对象
- 7)将Document对象中的所有属性取出,再封装回JavaBean对象中去,并加入到集合中保存,以备将之用
@Test
public void findIndexDB() throws Exception {
/**
* 参数一: IndexSearcher(Directory path)查询以xxx目录的索引库
*
* */
Directory directory = FSDirectory.open(new File("E:/createIndexDB"));
//创建IndexSearcher对象
IndexSearcher indexSearcher = new IndexSearcher(directory);
//创建QueryParser对象
/**
* 参数一: Version matchVersion 版本号【和上面是一样的】
* 参数二:String f,【要查询的字段】
* 参数三:Analyzer a【使用的拆词算法】
* */
Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_30);
QueryParser queryParser = new QueryParser(Version.LUCENE_30, "userName", analyzer);
//给出要查询的关键字
String keyWords = "钟";
//创建Query对象来封装关键字
Query query = queryParser.parse(keyWords);
//用IndexSearcher对象去索引库中查询符合条件的前100条记录,不足100条记录的以实际为准
TopDocs topDocs = indexSearcher.search(query, 100);
//获取符合条件的编号
for (int i = 0; i < topDocs.scoreDocs.length; i++) {
ScoreDoc scoreDoc = topDocs.scoreDocs[i];
int no = scoreDoc.doc;
//用indexSearcher对象去索引库中查询编号对应的Document对象
Document document = indexSearcher.doc(no);
//将Document对象中的所有属性取出,再封装回JavaBean对象中去
String id = document.get("id");
String userName = document.get("userName");
String sal = document.get("sal");
User user = new User(id, userName, sal);
System.out.println(user);
}
效果:
进一步说明Lucene代码
我们的Lucene程序就是大概这么一个思路:将JavaBean对象封装到Document对象中,然后通过IndexWriter把document写入到索引库中。当用户需要查询的时候,就使用IndexSearcher从索引库中读取数据,找到对应的Document对象,从而解析里边的内容,再封装到JavaBean对象中让我们使用。
Lucene第一篇【介绍Lucene、快速入门】的更多相关文章
- ZooKeeper学习总结 第一篇:ZooKeeper快速入门
1. 概述 Zookeeper是Hadoop的一个子项目,它是分布式系统中的协调系统,可提供的服务主要有:配置服务.名字服务.分布式同步.组服务等. 它有如下的一些特点: 简单 Zookeeper的核 ...
- Java并发包下锁学习第一篇:介绍及学习安排
Java并发包下锁学习第一篇:介绍及学习安排 在Java并发编程中,实现锁的方式有两种,分别是:可以使用同步锁(synchronized关键字的锁),还有lock接口下的锁.从今天起,凯哥将带领大家一 ...
- spring cloud系列教程第一篇-介绍
spring cloud系列教程第一篇-介绍 前言: 现在Java招聘中最常见的是会微服务开发,微服务已经在国内火了几年了,而且也成了趋势了.那么,微服务只是指spring boot吗?当然不是了,微 ...
- Mybatis第一篇【介绍、快速入门、工作流程】
什么是MyBatis MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为 ...
- .NET Core实战项目之CMS 第四章 入门篇-Git的快速入门及实战演练
写在前面 上篇文章我带着大家通过分析了一遍ASP.NET Core的源码了解了它的启动过程,然后又带着大家熟悉了一遍配置文件的加载方式,最后引出了依赖注入以及控制反转的概念!如果大家把前面几张都理解了 ...
- .NET Core实战项目之CMS 第五章 入门篇-Dapper的快速入门看这篇就够了
写在前面 上篇文章我们讲了如在在实际项目开发中使用Git来进行代码的版本控制,当然介绍的都是比较常用的功能.今天我再带着大家一起熟悉下一个ORM框架Dapper,实例代码的演示编写完成后我会通过Git ...
- .NET Core实战项目之CMS 第六章 入门篇-Vue的快速入门及其使用
写在前面 上面文章我给大家介绍了Dapper这个ORM框架的简单使用,大伙会用了嘛!本来今天这篇文章是要讲Vue的快速入门的,原因是想在后面的文章中使用Vue进行这个CMS系统的后台管理界面的实现.但 ...
- 第一篇:docker 简单入门(一)
本篇目录 写在最前面的话 docker概念介绍 镜像的概念.容器的概念 docker的安装介绍 写在最前面的话 由于此类文章博客园鉴定为简单文章,所以已经移到csdn[https://blog.csd ...
- 第一篇:《Kubernetes 入门介绍》
前言:本文是一篇 kubernetes(下文用 k8s 代替)的入门文章,将会涉及 k8s 的技术历史背景.架构.集群搭建.一个 Redis 的例子,以及如何使用 operator-sdk 开发 op ...
随机推荐
- OpenTK教程-2绘制一个三角形(正确的方法)
上一个教程向我们展示了如何在屏幕上画一个三角形.但是,我说过,那是一种古老的方式,即使它能够正常运行,但是现在这已经不是"正确"的方式.上篇文章中我们将几何发送到GPU的方式是所谓 ...
- dnf命令 (常用总结)
DNF是新一代的rpm软件包管理器.他首先出现在 Fedora 18 这个发行版中.而最近,它取代了yum,正式成为 Fedora 22 的包管理器. DNF包管理器克服了YUM包管理器的一些瓶颈,提 ...
- 张高兴的 Xamarin.Forms 开发笔记:为 Android 与 iOS 引入 UWP 风格的汉堡菜单 ( MasterDetailPage )
所谓 UWP 样式的汉堡菜单,我曾在"张高兴的 UWP 开发笔记:汉堡菜单进阶"里说过,也就是使用 Segoe MDL2 Assets 字体作为左侧 Icon,并且左侧使用填充颜色 ...
- Web初学-入门和tomcat介绍记录
一.WEB开发的相关知识 WEB,在英语中web即表示网页的意思,它用于表示Internet主机上供外界访问的资源. Internet上供外界访问的Web资源分为: 静态web资源(如html 页面) ...
- python+selenium自动化软件测试(第10章):测试驱动TDD
测试驱动开发模式,要求开发在写业务代码的时候,先写出测试代码,同时单元测试例子决定了如何来写产品的代码,并且不断的成功的执行编写的所有的单元测试例子,不断的完善单元测试例子进而完善产品代码, 这样随着 ...
- STL中set的用法
set,顾名思义,就是数学上的集合——每个元素最多只出现一次,并且set中的元素已经从小到大排好序. 头文件:#include<set> 常用的函数: begin() 返回set容 ...
- 学习笔记GAN003:GAN、DCGAN、CGAN、InfoGAN
GAN应用集中在图像生成,NLP.Robt Learning也有拓展.类似于NLP中的Actor-Critic. https://arxiv.org/pdf/1610.01945.pdf . Gen ...
- 在htnl中,<input tyle = "text">除了text外还有几种种新增的表单元素
input标签新增属性 <input list='list_t' type="text" name='user' placeholder='请输入姓名' va ...
- 使用Docker搭建简易的 Java Web 环境
![group_5622_0](http://ow20g4tgj.bkt.clouddn.com/2017-09-10-group_5622_0.png) 从[<从最简单的入手学习 Docker ...
- Unity3d&C#分布式游戏服务器ET框架介绍-组件式设计
前几天写了<开源分享 Unity3d客户端与C#分布式服务端游戏框架>,受到很多人关注,QQ群几天就加了80多个人.开源这个框架的主要目的也是分享自己设计ET的一些想法,所以我准备写一系列 ...