java实现建立索引
在数据库中建一个lucene库,插入一个tb_sku表,内含百万条目级别的数据。
附建表sql下载:
链接:https://pan.baidu.com/s/13FbFc5YmzaTcj0Rxh-O2Bg
提取码:ue7x
新建工程,
pom:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.4.RELEASE</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>luceneDemo</artifactId>
<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>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</dependency>
<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.48</version>
</dependency>
<!-- IK中文分词器 -->
<dependency>
<groupId>org.wltea.ik-analyzer</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.51</version>
</dependency>
</dependencies>
</project>
实体类:
@Data
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;
}
新建一个Dao接口及其实现,这里不展示代码
写一个测试类,通过测试方法建立索引:
@Test
public void createIndexTest() throws IOException {
//1. 采集数据
SkuDao skuDao = new SkuDaoImpl();
List<Sku> skuList = skuDao.querySkuList();
List<Document> docList = new ArrayList<>();
//2. 创建文档对象
for (Sku sku : skuList) {
Document document = new Document();
//创建域对象
document.add(new TextField("id", sku.getId(), Field.Store.YES));
document.add(new TextField("name", sku.getName(), Field.Store.YES));
document.add(new TextField("price", String.valueOf(sku.getPrice()), Field.Store.YES));
document.add(new TextField("image", sku.getImage(), Field.Store.YES));
document.add(new TextField("categoryName", sku.getCategoryName(), Field.Store.YES));
document.add(new TextField("brandName", sku.getBrandName(), Field.Store.YES));
//将文档对象放入文档集合中
docList.add(document);
}
//3. 创建分词器,StandardAnalyzer对英文分词效果好,对中文是单字分词
Analyzer analyzer = new StandardAnalyzer();
//4. 创建Directory目录对象,表示索引库的位置
Directory dir = FSDirectory.open(Paths.get("D:\\dir"));
//5. 创建IndexWriterConfig对象,指定切分词使用的分词器
IndexWriterConfig config = new IndexWriterConfig(analyzer);
//6. 创建IndexWriter输出流对象,指定输出的位置和使用的config初始化对象
IndexWriter indexWriter = new IndexWriter(dir,config);
//7. 写入文档到索引库
for (Document document : docList) {
indexWriter.addDocument(document);
}
//8. 释放资源
indexWriter.close();
}
运行前先建立对应的目录D:\dir
,运行后即可在目录下看到许多lucene建立索引后生成的存储文件

使用Luke工具查看生成的文件内容
打开工具,选择数据文件所在的目录

在overview标签页可以看到概览信息,包括域数、文档数、词数、词的频数统计

在document标签页可以看到单个的文档信息

在search标签页可以进行搜索

使用java查询数据
@Test
public void testSearch() throws ParseException, IOException {
//1. 创建分词器(对搜索的文本进行分词)
//注意;分词器要和创建索引时用的分词器一样
Analyzer analyzer = new StandardAnalyzer();
//2. 创建查询对象,第一个参数:默认查询域
//第二个参数:使用的分词器
QueryParser queryParser = new QueryParser("name",analyzer);
//3. 设置搜索关键词
Query query = queryParser.parse("华为手机");
//写成queryParser.parse("brandName: 华为手机");又可以指定查询域
//4. 创建Directory目录对象,指定索引库的位置
Directory dir = FSDirectory.open(Paths.get("D:\\dir"));
//5. 创建输入流对象
IndexReader indexReader = DirectoryReader.open(dir);
//6. 创建搜索对象
IndexSearcher indexSearcher = new IndexSearcher(indexReader);
//7. 搜索,并返回结果
//第二个参数:返回多少条消息,分页使用
TopDocs topDocs = indexSearcher.search(query, 10);
System.out.println("count: "+topDocs.totalHits);
//8. 获取结果集
ScoreDoc[] scoreDocs = topDocs.scoreDocs;
//9. 遍历结果集
if(scoreDocs != null){
for (ScoreDoc scoreDoc : scoreDocs) {
//获取查询到的文档唯一标识ID,这个ID是由lucene创建文档的时候分配的
int docID = scoreDoc.doc;
//通过ID读取文档
Document doc = indexSearcher.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("brandName: "+doc.get("brandName"));
System.out.println("categoryName: "+doc.get("categoryName"));
}
}
//10. 关闭流
indexReader.close();
}
查看输出:

原创文章,作者:彭晨涛,如若转载,请注明出处:https://www.codetool.top/article/lucene%e7%9a%84java%e5%ba%93%e4%bd%bf%e7%94%a8/