Lucene快速入门:
搭建环境
1.创建工程,引入坐标(springboot工程)
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<skipTests>true</skipTests>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.4.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-core</artifactId>
<version>7.7.2</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-analyzers-common</artifactId>
<version>7.7.2</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-queryparser</artifactId>
<version>7.7.2</version>
</dependency>
<!-- 测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- mysql数据库驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<!-- IK中文分词器 -->
<dependency>
<groupId>com.github.magese</groupId>
<artifactId>ik-analyzer</artifactId>
<version>8.1.0</version>
</dependency>
<!--web起步依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 引入thymeleaf -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- Json转换工具 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.56</version>
</dependency>
</dependencies>
2.创建数据库,准备百万条数据
..........
3.在磁盘创建Lucene索引文件和文档文件的存放目录(索引库)

索引流程
1.数据采集
在电商网站中,全文检索的数据源在数据库中,需要通过jdbc访问数据库中 sku 表的内容。
创建pojo对象:
public class Sku {
//商品主键id
private String id;
//商品名称
private String name;
//价格
private Integer price;
//库存数量
private Integer num;
//图片
private String image;
//分类名称
private String categoryName;
//品牌名称
private String brandName;
//规格
private String spec;
//销量
private Integer saleNum;
/********* get/set方法 *********/
}
创建DAO:
public class SkuDao {
public List<Sku> querySkuList() {
// 数据库链接
Connection connection = null;
// 预编译statement
PreparedStatement preparedStatement = null;
// 结果集
ResultSet resultSet = null;
// 商品列表
List<Sku> list = new ArrayList<Sku>();
try {
// 加载数据库驱动
Class.forName("com.mysql.jdbc.Driver");
// 连接数据库
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/lucene", "root", "root");
// SQL语句
String sql = "SELECT * FROM tb_sku";
// 创建preparedStatement
preparedStatement = connection.prepareStatement(sql);
// 获取结果集
resultSet = preparedStatement.executeQuery();
// 结果集解析
while (resultSet.next()) {
Sku sku = new Sku();
sku.setId(resultSet.getString("id"));
sku.setName(resultSet.getString("name"));
sku.setSpec(resultSet.getString("spec"));
sku.setBrandName(resultSet.getString("brand_name"));
sku.setCategoryName(resultSet.getString("category_name"));
sku.setImage(resultSet.getString("image"));
sku.setNum(resultSet.getInt("num"));
sku.setPrice(resultSet.getInt("price"));
sku.setSaleNum(resultSet.getInt("sale_num"));
list.add(sku);
}
} catch (Exception e) {
e.printStackTrace();
}
return list;
}
}
2.实现索引流程
/**
* 索引库维护
*/
public class IndexManagerTest {
/**
* 创建索引库
*/
@Test
public void testCreateIndex() throws IOException {
// 1. 采集数据
SkuDao skuDao = new SkuDao();
List<Sku> skus = skuDao.querySkuList();
// 创建文档集合
List<Document> docList = new ArrayList<>();
// 2. 创建Document文档对象
for (Sku sku : skus) {
Document document = new Document();
// 创建域对象,并且放入文档对象中
document.add(new TextField("id", sku.getId(), TextField.Store.YES));
document.add(new TextField("name", sku.getName(), TextField.Store.YES));
document.add(new TextField("price", String.valueOf(sku.getPrice()), TextField.Store.YES));
document.add(new TextField("image", sku.getImage(), TextField.Store.YES));
document.add(new TextField("categoryName", sku.getCategoryName(), TextField.Store.YES));
document.add(new TextField("brandName", sku.getBrandName(), TextField.Store.YES));
// 将文档对象放入到文档集合中
docList.add(document);
}
// 3. 创建分析器(分词器) StandardAnalyzer标准分词器,对英文分词效果好,对中文是单字分词
Analyzer analyzer = new StandardAnalyzer();
// 4. 创建IndexWriterConfig配置信息类,指定切分词使用的分词器
IndexWriterConfig config = new IndexWriterConfig(analyzer);
// 5. 创建Directory对象,声明索引库存储位置
Directory dir = FSDirectory.open(Paths.get("D:\\lucene"));
// 6. 创建IndexWriter写入对象,指定写入的位置和使用的config初始化对象
IndexWriter indexWriter = new IndexWriter(dir, config);
// 7. 把Document写入到索引库中
for (Document document : docList) {
indexWriter.addDocument(document);
}
// 8. 释放资源
indexWriter.close();
}
}
3.执行效果:在文件夹中出现了以下文件,表示创建索引成功

使用Luke查看索引:



搜索流程:
IndexSearcher搜索方法如下:

/**
* 测试搜索过程
*/
public class SearchTest {
@Test
public void testSearch() throws ParseException, IOException {
// 1.创建分词器(对搜索的关键词进行分词使用,分词器要和创建索引的时候使用的分词器一样)
Analyzer analyzer = new StandardAnalyzer();
// 2.创建Query搜索对象
QueryParser queryParser = new QueryParser("name", analyzer);
// 3.设置搜索关键词
// Query query = queryParser.parse("华为手机");// 默认在name域中查
Query query = queryParser.parse("brandName:生机谷");
// 4.创建Directory目录对象,指定索引库位置
Directory dir = FSDirectory.open(Paths.get("D:\\lucene"));
// 5.创建输入流对象
IndexReader indexReader = DirectoryReader.open(dir);
// 6.创建索引搜索对象IndexSearcher
IndexSearcher searcher = new IndexSearcher(indexReader);
// 7.使用索引搜索对象,执行搜索,返回结果集TopDocs
// 第二个参数表示返回多少条数据用于展示,分页使用
TopDocs topDocs = searcher.search(query, 10);
// 获取查询到的结果集总数
long total = topDocs.totalHits;
System.out.println(total);
// 8.获取结果集
ScoreDoc[] docs = topDocs.scoreDocs;
// 9.解析结果集
if(docs != null) {
for (ScoreDoc scoreDoc : docs) {
// 获取查询到的文档唯一标识,文档id,这个id是Lucene在创建文档的时候自动分配的
int docID = scoreDoc.doc;
// 通过文档id读取文档
Document doc = searcher.doc(docID);
System.out.println("-------------------");
// 通过域名,从文档中获取域值
System.out.println("id:" + doc.get("id"));
System.out.println("name:" + doc.get("name"));
System.out.println("price:" + doc.get("price"));
System.out.println("image:" + doc.get("image"));
System.out.println("categoryName:" + doc.get("categoryName"));
System.out.println("brandName:" + doc.get("brandName"));
}
}
// 10.释放资源
indexReader.close();
}
}
来源:https://www.cnblogs.com/roadlandscape/p/12547143.html