java lucene mysql_Lucene 02 - Lucene的入门程序(Java API的简单使用)

1 准备环境

JDK: 1.8.0_162

IDE: Eclipse Neon.3

数据库: MySQL 5.7.20

Lucene: 4.10.4(已经很稳定了,高版本对部分分词器支持不好)

2 准备数据

SET FOREIGN_KEY_CHECKS=0;

--------------------------------

Table structure for `book`

--------------------------------

DROP TABLE IF EXISTS `book`;

CREATE TABLE `book` (

`id` int(11) DEFAULT NULL,

`bookname` varchar(500) DEFAULT NULL,

`price` float DEFAULT NULL,

`pic` varchar(200) DEFAULT NULL,

`bookdesc` varchar(2000) DEFAULT NULL

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

--------------------------------

Records of book

--------------------------------

INSERT INTO `book` VALUES ('1', 'java从入门到精通', '56', '1.jpg', '《Java从入门到精通》是人民邮电出版社于 2010年出版的图书, 由国家863中部软件孵化器主编. 以零基础讲解为宗旨, 深入浅出地讲解Java的各项技术及实战技能. 本书从初学者角度出发, 通过通俗易懂的语言、丰富多彩的实例, 详细介绍了使用Java语言进行程序开发应该掌握的各方面技术.');

INSERT INTO `book` VALUES ('2', 'java web开发', '80', '2.jpg', 'Java Web, 是用Java技术来解决相关web互联网领域的技术总和. web包括: web服务器和web客户端两部分. Java在客户端的应用有java applet, 不过使用得很少, Java在服务器端的应用非常的丰富, 比如Servlet, JSP和第三方框架等等. Java技术对Web领域的发展注入了强大的动力. ');

INSERT INTO `book` VALUES ('3', 'lucene从入门到精通', '100', '3.jpg', '本书总结搜索引擎相关理论与实际解决方案, 并给出了 Java 实现, 其中利用了流行的开源项目Lucene和Solr, 而且还包括原创的实现. 本书主要包括总体介绍部分、爬虫部分、自然语言处理部分、全文检索部分以及相关案例分析. 爬虫部分介绍了网页遍历方法和如何实现增量抓取, 并介绍了从网页等各种格式的文档中提取主要内容的方法.');

INSERT INTO `book` VALUES ('4', 'lucene in action', '90', '4.jpg', '本书深入浅出地介绍了lucene——一个开源的使用java语言编写的全文搜索引擎开发包. 它通过浅显的语言、大量的图注、丰富的代码示例, 以及清晰的结构为读者呈现出作为优秀开源项目的lucene所体现的强大功能. ');

INSERT INTO `book` VALUES ('5', 'Lucene Java精华版', '80', '5.jpg', '本书总结搜索引擎相关理论与实际解决方案, 并给出了 Java 实现, 其中利用了流行的开源项目Lucene和Solr, 而且还包括原创的实现. 本书主要包括总体介绍部分、爬虫部分、自然语言处理部分、全文检索部分以及相关案例分析. 爬虫部分介绍了网页遍历方法和如何实现增量抓取, 并介绍了从网页等各种格式的文档中提取主要内容的方法. ');

3 创建工程

3.1 创建Maven Project(打包方式选jar即可)

35942be7159f2ef3d7420228aab429dc.png

3.2 配置pom.xml, 导入依赖

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

4.0.0

com.healchow

lucene-first

0.0.1-SNAPSHOT

jar

lucene-first

http://maven.apache.org

UTF-8

5.1.44

4.10.4

mysql

mysql-connector-java

${mysql.version}

org.apache.lucene

lucene-core

${lucene.version}

org.apache.lucene

lucene-analyzers-common

${lucene.version}

org.apache.lucene

lucene-queryparser

${lucene.version}

junit

junit

4.12

test

4 编写基础代码

4.1 编写图书POJO

public class Book {

private Integer id; // int(11) DEFAULT NULL,

private String bookname; // varchar(500) DEFAULT NULL,

private Float price; // float DEFAULT NULL,

private String pic; // varchar(200) DEFAULT NULL,

private String bookdesc; // varchar(2000) DEFAULT NULL

// Getters/Setters

@Override

public String toString() {

return "Book [id=" + id + ", bookname=" + bookname +

", price=" + price + ", pic=" + pic +

", bookdesc=" + bookdesc + "]";

}

}

4.2 编写图书DAO接口

public interface BookDao {

/**

* 查询全部图书

*/

List queryBookList();

}

4.3 实现图书DAO接口

public class BookDaoImpl implements BookDao {

/**

* 查询全部图书

*/

public List listAll() {

// 创建图书结果集合List

List books = new ArrayList();

Connection conn = null;

PreparedStatement preStatement = null;

ResultSet resultSet = null;

try {

// 加载驱动

Class.forName("com.mysql.jdbc.Driver");

// 创建数据库连接对象

conn = DriverManager.getConnection(

"jdbc:mysql://127.0.0.1:3306/lucene?useSSL=true",

"root",

"password");

// 定义查询SQL

String sql = "select * from book";

// 创建Statement语句对象

preStatement = conn.prepareStatement(sql);

// 执行语句, 得到结果集

resultSet = preStatement.executeQuery();

// 处理结果集

while (resultSet.next()) {

// 创建图书对象

Book book = new Book();

book.setId(resultSet.getInt("id"));

book.setBookname(resultSet.getString("bookname"));

book.setPrice(resultSet.getFloat("price"));

book.setPic(resultSet.getString("pic"));

book.setBookdesc(resultSet.getString("bookdesc"));

// 将查询到的结果添加到list中

books.add(book);

}

} catch (Exception e) {

e.printStackTrace();

} finally {

// 释放资源

try {

if (null != conn) conn.close();

if (null != preStatement) preStatement.close();

if (null != resultSet) resultSet.close();

} catch (Exception e) {

e.printStackTrace();

}

}

return books;

}

/**

* 测试功能的主方法

*/

public static void main(String[] args) {

// 创建图书Dao的实现对象

BookDao bookDao = new BookDaoImpl();

List books = bookDao.listAll();

// 如果结果不为空, 则便利输出

for (Book book : books) {

System.out.println(book);

}

}

}

测试结果如下:

7b0b8ba23fa7834bc45ef9afa207f57e.png

5 索引流程的实现

(1) 采集原始数据;

(2) 创建文档对象(Document);

(3) 创建分析器对象(Analyzer), 用于分词;

(4) 创建索引配置对象(IndexWriterConfig), 用于配置Lucene;

(5) 创建索引库目录位置对象(Directory), 指定索引库的存储位置;

(6) 创建索引写入对象(IndexWriter), 将文档对象写入索引库;

(7) 使用IndexWriter对象, 创建索引;

(8) 释放资源.

5.1 示例代码

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.Store;

import org.apache.lucene.document.TextField;

import org.apache.lucene.index.IndexWriter;

import org.apache.lucene.index.IndexWriterConfig;

import org.apache.lucene.store.Directory;

import org.apache.lucene.store.FSDirectory;

import org.apache.lucene.util.Version;

public class IndexManager {

/**

* 创建索引功能的测试

* @throws Exception

*/

@Test

public void createIndex() throws IOException{

// 1. 采集数据

BookDao bookDao = new BookDaoImpl();

List books = bookDao.listAll();

// 2. 创建文档对象

List documents = new ArrayList();

for (Book book : books) {

Document document = new Document();

// 给文档对象添加域

// add方法: 把域添加到文档对象中, field参数: 要添加的域

// TextField: 文本域, 属性name:域的名称, value:域的值, store:指定是否将域值保存到文档中

document.add(new TextField("bookId", book.getId() + "", Store.YES));

document.add(new TextField("bookName", book.getBookname(), Store.YES));

document.add(new TextField("bookPrice", book.getPrice() + "", Store.YES));

document.add(new TextField("bookPic", book.getPic(), Store.YES));

document.add(new TextField("bookDesc", book.getBookdesc(), Store.YES));

// 将文档对象添加到文档对象集合中

documents.add(document);

}

// 3. 创建分析器对象(Analyzer), 用于分词

Analyzer analyzer = new StandardAnalyzer();

// 4. 创建索引配置对象(IndexWriterConfig), 用于配置Lucene

// 参数一:当前使用的Lucene版本, 参数二:分析器

IndexWriterConfig indexConfig = new IndexWriterConfig(Version.LUCENE_4_10_2, analyzer);

// 5. 创建索引库目录位置对象(Directory), 指定索引库的存储位置

File path = new File("/your_path/index");

Directory directory = FSDirectory.open(path);

// 6. 创建索引写入对象(IndexWriter), 将文档对象写入索引

IndexWriter indexWriter = new IndexWriter(directory, indexConfig);

// 7. 使用IndexWriter对象创建索引

for (Document doc : documents) {

// addDocement(doc): 将文档对象写入索引库

indexWriter.addDocument(doc);

}

// 8. 释放资源

indexWriter.close();

}

}

5.2 测试结果

说明: 只要看到以下文件, 说明索引已经创建成功了:

14a9ca4b7178dd2d1c6cc3ac45ed690f.png

6 使用Luke工具查看索引

47461c99ea56aaa77ba997d1fc3e3197.png

6.1 使用说明

Windows OS下,双击运行start.bat文件(前提是需要配置jdk的环境变量);

Mac OS下, 在终端中进入当前目录, 然后键入 ./start.sh 即可运行.

6.2 运行界面一

e430a444767025fd2b19f9378ec0a538.png

6.3 运行界面二

d2e555bec90aea677692bb7f65e76390.png

6.4 运行界面三

c5bd9d7e91a6d4b1b1a46f7175eba085.png

7 检索流程的实现

(1) 创建分析器对象(Analyzer), 用于分词;

(2) 创建查询对象(Query);

(3) 创建索引库目录位置对象(Directory), 指定索引库的位置;

(4) 创建索引读取对象(IndexReader), 用于读取索引;

(5) 创建索引搜索对象(IndexSearcher), 用于执行搜索;

(6) 使用IndexSearcher对象, 执行搜索, 返回搜索结果集TopDocs;

(7) 处理结果集;

(8) 释放资源.

7.1 使用Luke工具搜索

f984b4a0ed79146dffb486a7980ee986.png

bookName:lucene —— 表示搜索bookName域中包含有lucene.

7.2 示例代码

/**

* 检索索引功能的测试

* @throws Exception

*/

@Test

public void searchIndexTest() throws Exception {

// 1. 创建分析器对象(Analyzer), 用于分词

Analyzer analyzer = new StandardAnalyzer();

// 2. 创建查询对象(Query)

// 2.1 创建查询解析器对象

// 参数一:默认的搜索域, 参数二:使用的分析器

QueryParser queryParser = new QueryParser("bookName", analyzer);

// 2.2 使用查询解析器对象, 实例化Query对象

Query query = queryParser.parse("bookName:lucene");

// 3. 创建索引库目录位置对象(Directory), 指定索引库位置

Directory directory = FSDirectory.open(new File("/your_path/index"));

// 4. 创建索引读取对象(IndexReader), 用于读取索引

IndexReader indexReader = DirectoryReader.open(directory);

// 5. 创建索引搜索对象(IndexSearcher), 用于执行索引

IndexSearcher searcher = new IndexSearcher(indexReader);

// 6. 使用IndexSearcher对象执行搜索, 返回搜索结果集TopDocs

// 参数一:使用的查询对象, 参数二:指定要返回的搜索结果排序后的前n个

TopDocs topDocs = searcher.search(query, 10);

// 7. 处理结果集

// 7.1 打印实际查询到的结果数量

System.out.println("实际查询到的结果数量: " + topDocs.totalHits);

// 7.2 获取搜索的结果数组

// ScoreDoc中有文档的id及其评分

ScoreDoc[] scoreDocs = topDocs.scoreDocs;

for (ScoreDoc scoreDoc : scoreDocs) {

System.out.println("= = = = = = = = = = = = = = = = = = =");

// 获取文档的id和评分

int docId = scoreDoc.doc;

float score = scoreDoc.score;

System.out.println("文档id= " + docId + " , 评分= " + score);

// 根据文档Id, 查询文档数据 -- 相当于关系数据库中根据主键Id查询数据

Document doc = searcher.doc(docId);

System.out.println("图书Id: " + doc.get("bookId"));

System.out.println("图书名称: " + doc.get("bookName"));

System.out.println("图书价格: " + doc.get("bookPrice"));

System.out.println("图书图片: " + doc.get("bookPic"));

System.out.println("图书描述: " + doc.get("bookDesc"));

}

// 8. 关闭资源

indexReader.close();

}

7.3 测试结果

9af8befb7822a8469f07659cca0da1d1.png

7.4 结果说明

(1) 索引库中包含索引域和文档域;

(2) 索引域保存索引数据(倒排索引), 用于索引;

(3) 文档域中保存文档数据, 用于搜索获取数据.

7.5 IndexSearcher方法

方法

说明

indexSearcher.search(query, n)

根据Query搜索, 返回评分最高的n条记录

indexSearcher.search(query,filter,n)

根据Query搜索, 添加过滤策略, 返回评分最高的n条记录

indexSearcher.search(query, n, sort)

根据Query搜索, 添加排序策略, 返回评分最高的n条记录

indexSearcher.search(booleanQuery, filter, n, sort)

根据Query搜索, 添加过滤策略, 添加排序策略, 返回评分最高的n条记录

版权声明

作者: 马瘦风

出处: 博客园 马瘦风的博客

您的支持是对博主的极大鼓励, 感谢您的阅读.

本文版权归博主所有, 欢迎转载, 但请保留此段声明, 并在文章页面明显位置给出原文链接, 否则博主保留追究相关人员法律责任的权利.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值