像百度,京东,淘宝一样的搜索功能使用Lucene实现电商项目中图书类商品的索引和搜索功能的入门示例...

1.1 需求

使用Lucene实现电商项目中图书类商品的索引和搜索功能。

1.2 配置步骤说明

1)搭建环境(先下载Lucene

2)创建索引库

3)搜索索引库

 

1.3 配置步骤

1.3.1 第一部分:搭建环境(创建项目,导入包)

前提:已经创建好了数据库(直接导入book.sql文件)

 

 

 

1.3.1.1 第一步下载Lucene

Lucene是开发全文检索功能的工具包,使用时从官方网站下载,并解压。

官方网站:http://lucene.apache.org/ 

下载地址http://archive.apache.org/dist/lucene/java/

下载版本:4.10.3(要求:jdk1.7及以上)

 

核心包lucene-core-4.10.3.jar(附常用API

 

 

 

1.3.1.2 第二步创建项目导入包

mysql5.1驱动包:mysql-connector-java-5.1.7-bin.jar

核心包:lucene-core-4.10.3.jar

分析器通用包:lucene-analyzers-common-4.10.3.jar

查询解析器包:lucene-queryparser-4.10.3.jar

 

1.3.2 第二部分:创建索引

步骤说明:

1)采集数据

2)将数据转换成Lucene文档

3)将文档写入索引库,创建索引

 

1.3.2.1 第一步:采集数据

Lucene全文检索,不是直接查询数据库,所以需要先将数据采集出来。

 

1)创建Book

public class Book {

private Integer bookId;  // 图书ID

private String name;   // 图书名称

private Float price;    // 图书价格

private String pic;    // 图书图片

private String description; // 图书描述

    // 补全get\set方法

}

 

2)创建一个BookDao

package cn.lxm.lucene.dao;

 

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.PreparedStatement;

import java.sql.ResultSet;

import java.sql.SQLException;

import java.util.ArrayList;

import java.util.List;

 

import cn.lxm.lucene.pojo.Book;

 

public class BookDao {

public List<Book> getAll() {

// 数据库链接

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/lucene", "root", "111");

 

// SQL语句

String sql = "SELECT * FROM book";

// 创建preparedStatement

preparedStatement = connection.prepareStatement(sql);

 

// 获取结果集

resultSet = preparedStatement.executeQuery();

 

// 结果集解析

while (resultSet.next()) {

Book book = new Book();

book.setBookId(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();

 

}finally {

 

if(null!=resultSet){

try {

resultSet.close();

} catch (SQLException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

if(null!=preparedStatement){

try {

preparedStatement.close();

} catch (SQLException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

if(null!=connection){

try {

connection.close();

} catch (SQLException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

return list;

}

}

 

3)创建一个测试类BookDaoTest

package cn.lxm.lucene.test;

 

import java.util.List;

 

import org.junit.Test;

import cn.lxm.lucene.dao.BookDao;

import cn.lxm.lucene.pojo.Book;

 

public class BookDaoTest {

 

@Test

public void getAll(){

BookDao dao = new BookDao();

List<Book> books = dao.getAll();

 

for (Book book : books) {

System.out.println("图书id:"+book.getBookId()+",图书名称:"+book.getName());

}

}

}

 

4)测试结果,采集数据成功

 

 

 

1.3.2.2 第二步:将数据转换成Lucene文档

Lucene是使用文档类型来封装数据的,所有需要先将采集的数据转换成文档类型。其格式为:

 

 

修改BookDao,新增一个方法,转换数据

public List<Document> getDocuments(List<Book> books){

// Document对象集合

List<Document> docList = new ArrayList<Document>();

// Document对象

Document doc = null;

for (Book book : books) {

// 创建Document对象,同时要创建field对象

doc = new Document();

// 根据需求创建不同的Field

Field id = new TextField("id", book.getBookId().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 desc = new TextField("description", book.getDescription(), Store.YES);

// 把域(Field)添加到文档(Document)中

doc.add(id);

doc.add(name);

doc.add(price);

doc.add(pic);

doc.add(desc);

 

docList.add(doc);

}

return docList;

}

 

1.3.2.3 第三步创建索引库

说明Lucene是在将文档写入索引库的过程中,自动完成分词、创建索引的。因此创建索引库,从形式上看,就是将文档写入索引库!

 

修改测试类,新增createIndex方法

@Test

public void createIndex(){

try {

BookDao dao = new BookDao();

 

// 分析文档,对文档中的field域进行分词

Analyzer analyzer = new StandardAnalyzer();

// 创建索引

// 1) 创建索引库目录

Directory directory = FSDirectory.open(new File("D:\\A"));

// 2) 创建IndexWriterConfig对象

IndexWriterConfig cfg = new IndexWriterConfig(Version.LATEST, analyzer);

// 3) 创建IndexWriter对象

IndexWriter writer = new IndexWriter(directory, cfg);

// 4) 通过IndexWriter对象添加文档对象(document

writer.addDocuments(dao.getDocuments(dao.getAll()));

 

// 5) 关闭IndexWriter

writer.close();

System.out.println("创建索引库成功");

 

} catch (Exception e) {

e.printStackTrace();

}

}

 

测试结果,创建成功!!!

 

 

 

1.3.3 第三部分搜索索引

1.3.3.1 说明

搜索的时候需要指定搜索哪一个域(也就是字段),并且,还要对搜索的关键词做分词处理。

 

1.3.3.2 执行搜索

修改测试类,新增searchDocumentByIndex方法

@Test

public void searchDocumentByIndex(){

try {

// 1、 创建查询(Query对象)

// 创建分析器

Analyzer analyzer = new StandardAnalyzer();

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

Query query = queryParser.parse("name:java教程");

// 2、 执行搜索

// a) 指定索引库目录

Directory directory = FSDirectory.open(new File("D:\\A"));

// b) 创建IndexReader对象

IndexReader reader = DirectoryReader.open(directory);

// c) 创建IndexSearcher对象

IndexSearcher searcher = new IndexSearcher(reader);

// d) 通过IndexSearcher对象执行查询索引库,返回TopDocs对象

// 第一个参数:查询对象

// 第二个参数:最大的n条记录

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

// e) 提取TopDocs对象中前n条记录

ScoreDoc[] scoreDocs = topDocs.scoreDocs;

System.out.println("查询出文档个数为:" + topDocs.totalHits);

for (ScoreDoc scoreDoc : scoreDocs) {

// 文档对象ID

int docId = scoreDoc.doc;

Document doc = searcher.doc(docId);

// f) 输出文档内容

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

System.out.println("文档id:" + docId);

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

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

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

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

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

}

// g) 关闭IndexReader

reader.close();

} catch (Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

测试结果,非常成功!!!

 

 

转载于:https://www.cnblogs.com/bky-lxm/p/10946626.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值