开发者学堂课程【Lucene 知识精讲与实战(上): 入门案例(索引过程)】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/700/detail/12333
入门案例(索引过程)
内容介绍:
一、简介
二、演示
三、索引过程
四、索引代码
一、简介
在索引的过程当中,要先在硬盘的一个根目录里创建一个文件夹,创建的文件夹叫做缩影库,用来存放生成的索引文件。lucene 的索引文件就相当于字典的目录。文档的文件,就相当于字典中的内容。
新建一个文件夹,文件夹目录不能出现中文或者是空格,文件夹叫做索引库。原因是会往里边存 lucene 的索引文件和文档文件。
到时候会用 dbc 把商品表中大概100万条左右的数据通过 gdbc 读取出来,读取出来之后对它进行切分词,切分词之后,这个目录也就是索引和文档,然后把索引和文档写入到文件夹当中,这个文件夹叫做索引库。
二、演示
在文档当中有它的实体类 pogo 和它的 DAO 接口,DAO 是用 GDPC 来写的,那么 DAO 接口唯一方法是查询 sku 表,商品表它里边的所有数据将近100万条给它查出来,查出来之后,再利用这些数据,组成文档组成索引等等。
1.创建 sku 实体类
来到的 idea 开发工具,在这里边在pogo里边创建sku类。
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;
2.创建 DAO
右键新建接口文件,接口文件叫做 sku DAO,再来创建它的实现类文件,实现类文件叫做 sku dao impl,impl 实现 sku。
public interface skuDao {
查询所有的 sku 数据*
@return
public List<sku> queryskuList();
3.创建 DAO 接口实现类
public class SkuDaoImpl implements SkuDao
public List<sku> querySkuList() {
// 数据库链接
Connection connection=null;
//预编译statement
Preparedstatementpreparedstatement=null;
// 结果集
Resultset resultset=null;// 商品列表
List<Sku> list=new ArrayList<Sku>();
创建连接,有粒子集合,下边去连接的 my circle 数据库,是本地的这306端口,库名叫做 lucene.
try {
//加载数据库驱动
Class.forName("com.mysq1.jdbc.Driver");
// 连接数据库
connection=DriverManager.getConnection("jdbc:mysq1://localhost:3306/lucene","root","admin");
这个是数据库的用户名密码,用户名是 root,密码叫做 ADMIN。
//SOL 语句
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.setategoryName(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;
最后这个集合当中会包含近小100万个这个数据。
三、索引过程
回到的测试类,由于现在是要来测试索引过程,所以打开 text index,manager 打开它,在这里创建索引的过程,索引库维护,所以在下边写测试方法,public 外的还有它的方法名: Create index。
先来创建由于这里使用了给 java util 作为测试,在上边加上注解的test注解,引入这个 java util 测试的这个注解。
那么再来往下就是他索引的过程了,在这里写上注释,叫做创建索引。再下边来写它的实现。
1.采集数据
采集数据其实就利用刚才写好的代码到数据库当中,把它数据给它读出来。
2.创建文档对象
在创建文档对象的过程当中,会创建它一个域,然后往这个文档对象当中去添加。域值就是在存储结构图当中,读出来的一一条的数据库当中的数据,要先组成把一一条数据组成一个文档对象,那么在一个的文档对象当中是有一个域的,这个域它是ky6的兼职对格式有域名,有域值,于是就可以把它的查询出来的数据的字段名作为它的域名,把查询出来某一个字段,它的值作为它的域值。一个文档就相当于一一条数据。如果说数据库当中有将近100万条数据,创建完后索引库当中也就相当于有将近小100万个文档。
3.创建分词器
因为文档对象有了,要把文档对象当中的内容给它提取出来,然后进行切分词,把一句一句话切分成一个词。按照全文检索的原理,切完词之后把这个词的索引,然后这个时候在查的时候就可以通过索引,然后找文档,创建分子器。
4.创建 Directory 目录对象,目录对象表示索引库的位置
目录对象表示索引库的位置,即需要找到它存到哪,传到U盘的哪个位置。
5.创建 IndexWriterConfig 对象,这个对象中指定切分词使用的分词器。
即输出流的它的初始化对象,出始化对象当中,指定了要使用的分词器,即指定切分词使用的分时器。
6.创建 IndexWriter 输出流对象,指定输出的位置和使用的 confia 初始化对象
在这个对象当中,会指定输出的位置和使用的和分子器对象的对象使用的看初始换,到时候会通过输出流,把索引和文档都输出到硬盘下边刚才建立的索引库。
7.写入文档到索引库
8.释放资源。
这个就是一个完整的创建索引库的过程。
四、索引代码
import java.util.ArrayList;
import java.util.list;
*索引库维护
public class TestIndexManager {
/**
*创建索引库*/
@Test
public void createIndexTest(()
//1.采集数据
SkuDao skuDao=newSkuDaoImp1();
List<Sku> skuList=skuDao.querySkuList();
List<Document> docList=new ArrayList<>():
for (Sku sku :skuList){
//把数据都从数据库当中通过口语句然后给它读出来,叫做sku。因为这个集合当中它包含了将近小100万条。那么这个文档对象创建出来之后应该也是一个集合,所以说这里需要提前的把放文档的集合对象画出来,叫做 document。注意看这里包别选错了,一定要选择 lucene 的。点 document,那么这个叫做 DOC list。
//2.创建文档对象
// 再来看创建文档对象,要根据这个数据创建,所以我这里边应该for循环,将谁 for 循环,将集合 for 循环之后,循环出来的是一个的库存对象也可以叫做商品对象。把它当成电商当中商品的数据,那么在这个对象当中,我要把它里边的数据取出来之后,作为一个域,即它里面一个值就作为一个域。
d
ocument document = new Document()
//创建域对象并且放入文档对象中
document.add(new TextField());
那么下面来首先创建文档对象,document 创建一个的文档对象,看一下这个包对不对,包的话 lucene 的没问题,那么在这里,创建预对象。想要往文档当中放什么样的数据,就要创建多少个域对象,
document.add(new TextField("name",sku.getName(),Field.Store.YES));
比如在数据库导进来表当中,它的结构包括,组件AD名称,它的价格,它的库存量,它的图片,以及这个商品的分类,商品的品牌,商品的规格,商品的销量,并不是说所有的数据都要给它放到数用户的,要看搜索的时候你想搜索哪些内容,那么AD一般基本上都会放。因为 Ad是数据库当中这个表的它的组件,它的唯一标识,要把它引入到数据库当中。
还有名称一般都是根据名称来查询,查询的时候还有可能根据什么查,根据价格查,根据图片查,这个是没有的,一般不根据图片差,但是一般我要显示的时候把它显示到页面,把某一个商品内容显示到页面,一般会显示它这个商品长什么样,它的智力图片,所以说对于图片的话,其实也是要给它导入到所用户的。查询的时候根据分类查,这样的数据也要引入到数据库当中。
创建域的时候,add 这个方法是将创建出来的域加入到这个文档对象当中,然后把的创建出来的预对象创建预对象,并且放入文档对象中。
那么在文本域中我点开看它这里边传什么样的数据?这里边传数据的话,传三个数据,那么第一个参数叫做域名,第二个参数叫做预值,第三个参数叫做是否存储。这里边打开看一下,域名根据它的字段名来进行起名就行了。
假如放的第一个叫做 ID,那么再来看她的域值的话,就是 sku.get ID 它的值这个值是使用类型的。第三个参数叫做 store,store 这里边叫做是否存储,先给它放成yes。
下面复制粘贴很多份并进行修改:
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.StoreYES));
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=newStandardAnalyzer);
创建分词器,就是要对这个文档里边的内容,它的一句一句话提取出来,分成一个一个词组成缩影,所以我要创建分词器对象,分词器对象叫做 and nice and letter。选择 lucene 为准备的标准分子器,。那么分子器它的分子效果怎么样?是单带的,按道理标准分词器,它对英文的分词效果非常好。标准分词器。对英文分词效果好。对中文是单字分词,也就是一个字,就认为是一个它是这么分的。
//4.创建 Directory 目录对象,目录对象表示索引库的位置
Directory dir=FSDirectory.open(Paths.get("E:\\dir"));
//5.创建 IndexWriterConfig 对象,这个对象中指定切分词使用的分词器 IndexWriterConfig config=newIndexWriterConfig(analyzer):
//6.创建 Indexwriter 输出流对象,指定输出的位置和使用的 config 初始化对象 IndexWriter indexWriter =new IndexWriter(dir,config);
//7.写入文档到索引库
for (Document doc :docList) {
indexWriter.addDocument(doc);
//8.释放资源
indexWriter.close();
到目前为止,创建指引库代码小例子就完成了,在刚才的代码当中,创建文档对象,并且把文档对象的内容提出来,通过分时器进行切分词,没有看到创建索引的切分词之后,这个词要来组建索引,那么组件索引没有代码。流输出的时候,他就会利用分词器,然后把文档中的内容切分出来,组成一个词,而组成的词组成索引的过程是在 lucene 的底层代码来完成的,不用自己亲手来写。
它执行过程大概需要将近10来秒,因为这里的数据量大概是将近小100万条,所以它这个过程可能会稍微慢一些。同时可以打开 dir 文件里面就包含了数据的索引文件和文档文件。