目录:
1、lucene介绍
2、Lucene实现全文检索的流程
2.1、索引流程概述
2.2、Lucene索引文件的逻辑结构
3、入门程序
3.1、项目搭建
3.2、索引
3.3、搜索
4、field域
5、索引维护
6、搜索
7、相关度排序
8、中文分词器
1、lucene介绍 <--返回目录
* 什么是lucene
- Lucene是Apache的一个全文检索引擎工具包,通过lucene可以让程序员快速开发一个全文检索功能。
- 引擎:核心组件
- 工具包:jar包、类库
* 全文检索的应用场景
- 搜索引擎:例如百度
- 【站内搜索】
- 文件系统的搜索
* Lucene和搜索引擎不是一回事
- Lucene是一个工具包,它不能独立运行,不能单独对外提供服务。
- 搜索引擎可以独立运行对外提供搜索服务。
* 全文检索定义
- 全文检索首先对要搜索的文档进行分词,然后形成索引,通过查询索引来查询文档。
- 全文检索就是先创建索引,然后根据索引来进行搜索的过程,就叫全文检索。
- 比如:字典,
字典的偏旁部首页,就类似于luence的索引
字典的具体内容,就类似于luence的文档内容
2、Lucene实现全文检索的流程 <--返回目录
* 全文检索的流程:索引流程、搜索流程
- 索引流程:采集数据--》文档处理-存储到索引库中
- 搜索流程:输入查询条件--》通过lucene的查询器查询索引--》从索引库中取出结果--》视图渲染
- Lucene本身不能进行视图渲染。
2.1、索引流程概述 <--返回目录
- 为什么采集数据
全文检索搜索的内容的格式是多种多样的,比如:视频、mp3、图片、文档等等。对于这种格式不同的数据,
需要先将他们采集到本地,然后统一封装到lucene的文档对象中,也就是说需要将存储的内容进行统一才能对它进行查询。
- 采集数据的方式
- 对于互联网中的数据,使用爬虫工具(http工具)将网页爬取到本地
- 对于数据库中的数据,使用jdbc程序进行数据采集
- 对于文件系统的数据,使用io流采集
- 因为目前搜索引擎主要搜索数据的来源是互联网,搜索引擎使用一种爬虫程序抓取网页(通过http抓取html网页信息),以下是一些爬虫项目:
** Solr(http://lucene.apache.org/solr),solr是apache的一个子项目,支持从关系数据库、xml文档中提取原始数据。
** Nutch(http://lucene.apache.org/nutch), Nutch是apache的一个子项目,包括大规模爬虫工具,能够抓取和分辨web网站数据。
** jsoup(http://jsoup.org/),jsoup 是一款Java 的HTML解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API,
可通过DOM,CSS以及类似于jQuery的操作方法来取出和操作数据。
** heritrix(http://sourceforge.net/projects/archive-crawler/files/),Heritrix 是一个由 java 开发的、开源的网络爬虫,
用户可以使用它来从网上抓取想要的资源。其最出色之处在于它良好的可扩展性,方便用户实现自己的抓取逻辑。
2.2、Lucene索引文件的逻辑结构 <--返回目录
文档域
文档域存储的信息就是采集到的信息,通过Document对象来存储,具体说是通过Document对象中field域来存储数据。
比如:数据库中一条记录会存储一个一个Document对象,数据库中一列会存储成Document中一个field域。
文档域中,Document对象之间是没有关系的。而且每个Document中的field域也不一定一样。
索引域
索引域主要是为了搜索使用的。索引域内容是经过lucene分词之后存储的。
倒排索引表
传统方法是先找到文件,如何在文件中找内容,在文件内容中匹配搜索关键字,这种方法是顺序扫描方法,数据量大就搜索慢。
倒排索引结构是根据内容(词语)找文档,倒排索引结构也叫反向索引结构,包括索引和文档两部分,索引即词汇表,
它是在索引中匹配搜索关键字,由于索引内容量有限并且采用固定优化算法搜索速度很快,找到了索引中的词汇,词汇与文档关联,
从而最终找到了文档。
3、入门程序 <--返回目录
3.1、项目搭建 <--返回目录
* 需求:使用lucene完成对数据库中图书信息的索引和搜索功能。
* 环境准备
- Jdk:1.7及以上
- Lucene:4.10(从4.8版本以后,必须使用jdk1.7及以上)
- Ide:eclipse
- 数据库:mysql5.x
* 数据库脚本初始化--book.sql
* Lucene下载
- Lucene是开发全文检索功能的工具包,使用时从官方网站下载,并解压。
** 官方网站:http://lucene.apache.org/
** 目前最新版本:5.4.0
** 下载地址:http://archive.apache.org/dist/lucene/java/
下载版本:4.10.3
JDK要求:1.7以上(从版本4.8开始,不支持1.7以下)
* 工程搭建
- Mysql驱动包
- Analysis的包 lucene-analyzers-common-xxx.jar
- Core包 lucene-core-xxx.jar
- QueryParser包 lucene-queryparser-xxx.jar
- Junit包(非必须)
3.2、索引 <--返回目录
采集数据(使用jdbc从数据库中获取数据)
pojo类
public class Book { private Integer id;// 图书ID private String name;// 图书名称 private Float price;// 图书价格 private String pic;// 图书图片 private String description;// 图书描述 // getXxx和setXxx省略 }
接口和实现类
public class BookDaoImpl implements BookDao { @Override public List<Book> queryBooks() { // 数据库链接 Connection connection = null; // 预编译statement PreparedStatement preparedStatement = null; // 结果集 ResultSet resultSet = null; // 图书列表 List<Book> list = new ArrayList<Book>(); try { // 加载数据库驱动 Class.forName("com.mysql.jdbc.Driver"); // 连接数据库 connection = DriverManager.getConnection( "jdbc:mysql://localhost:3306/solr", "root", "root"); // SQL语句 String sql = "SELECT * FROM book"; // 创建preparedStatement preparedStatement = connection.prepareStatement(sql); // 获取结果集 resultSet = preparedStatement.executeQuery(); // 结果集解析 while (resultSet.next()) { Book book = newBook(); book.setId(resultSet.getInt("id")); book.setName(resultSet.getString("name")); book.setPrice(resultSet.getFloat("price")); book.setPic(resultSet.getString("pic")); book.setDescription(resultSet.getString("description")); list.add(book); } } catch (Exception e) { e.printStackTrace(); } return list; } }
创建索引(将采集的数据存储到索引库中)索引库/索引文件 ----索引域+文档域
@Test public void createIndex() throws Exception { // 采集数据 BookDao dao = new BookDaoImpl(); List<Book> list = dao.queryBooks(); // 将采集到的数据封装到Document对象中 List<Document> docList = new ArrayList<>(); Document document; for (Book book : list) { document = new Document(); // store:如果是yes,则说明存储到文档域中 // 图书ID Field id = new TextField("id", book.getId().toString(), Store.YES); // 图书名称 Field name = new TextField("name", book.getName(), Store.YES); // 图书价格 Field price = new TextField("price", book.getPrice().toString(), Store.YES); // 图书图片地址 Field pic = new TextField("pic", book.getPic(), Store.YES); // 图书描述 Field description = new TextField("description", book.getDescription(), Store.YES); // 将field域设置到Document对象中 document.add(id); document.add(name); document.add(price); document.add(pic); document.add(description); docList.add(document); } // 创建分词器,标准分词器 Analyzer analyzer = new StandardAnalyzer(); // 创建IndexWriterConfig IndexWriterConfig cfg = new IndexWriterConfig(Version.LUCENE_4_10_3, analyzer); // 指定索引库的地址 File indexFile = new File("E:\\11-index\\hm19\\"); Directory directory = FSDirectory.open(indexFile); IndexWriter writer = new IndexWriter(directory, cfg); // 通过IndexWriter对象将Document写入到索引库中 for (Document doc : docList) { writer.addDocument(doc); } // 关闭writer writer.close(); }
什么是分词
** 分词:将field域中的内容一个个的分词
** 过滤:将分好的词进行过滤,比如去掉标点符号、大写转小写、词型还原(复数转单数等)、停用词过滤
** 停用词:单独应用没有特殊意义的词,比如is a
分词例子:Lucene is a Java full-text search engine.
Lucene is a Java full-text search engine. 第一步:分词 Lucene is a Java Full - text search engine . 第二步:过滤 去掉标点符号 Lucene is a Java Full text search engine 去掉停用词 Lucene Java Full text search engine 大写转小写 lucene java full text search engine