Lucene的总结(一)

 

 

一、

  1. 什么是Lucene?

Lucene是apache下的一个开源的全文检索引擎工具包。它为软件开发人员提供一个简单易用的工具包(类库),以方便的在目标系统中实现全文检索的功能。

   注意

Lucene和搜索引擎是不同的,Lucene是一套用java或其它语言写的全文检索的工具包。它为应用程序提供了很多个api接口去调用,可以简单理解为是一套实现全文检索的类库。搜索引擎是一个全文检索系统,它是一个单独运行的软件系统

      2.全文检索定义

全文检索首先将要查询的目标文档中的词提取出来,组成索引,通过查询索引达到搜索目标文档的目的。这种先建立索引,再对索引进行搜索的过程就叫全文检索(Full-text Search

二、

  1. Lucene实现全文检索的流程

                    

               

全文检索的流程分为两大部分:索引流程、搜索流程。

  1. 索引流程:即采集数据à构建文档对象à分析文档(分词)à创建索引。
  2. 搜索流程:即用户通过搜索界面à创建查询à执行搜索,搜索器从索引库搜索à渲染搜索结果。

 

   2、Lucene的下载

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

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

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

 

下载版本:4.10.3(建议使用)

JDK要求:1.7以上(从版本4.8开始,不支持1.7以下)

   

​​​​​​​​​​​​​​    3、索引流程

   对文档索引的过程,就是将用户要搜索的文档内容进行索引,然后把索引存储在索引库(index)中。

    4、

三、

   1、入门程序 

​​​​​​​           第一步:创建java工程

           

        

​​​​​​​           第二步:添加jar包

     入门程序只需要添加以下jar包:

  • 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
  • junit包:junit-4.9.jar

           第三步:代码实现

    创建与数据库相对应的po类

public class Book {
	// 图书ID
	private Integer id;
	// 图书名称
	private String name;
	// 图书价格
	private Float price;
	// 图书图片
	private String pic;
	// 图书描述
	private String description;
}

   创建dao层

public interface BookDao {
	// 图书查询
	public List<Book> queryBookList() throws Exception;
}
public class BookDaoImpl implements BookDao {

	@Override
	public List<Book> queryBookList() throws Exception {
		// 数据库链接
		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/solr", "root", "root");

			// SQL语句
			String sql = "SELECT * FROM book";
			// 创建preparedStatement
			preparedStatement = connection.prepareStatement(sql);

			// 获取结果集
			resultSet = preparedStatement.executeQuery();

			// 结果集解析
			while (resultSet.next()) {
				Book book = new Book();
				book.setId(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();
		}

		return list;
	}

}

四、

​​​​​​​     1、索引文件的逻辑结构

                      

 

  • 文档域:

对非结构化的数据统一格式为document文档格式,一个文档有多个field域,不同的文档其field的个数可以不同,建议相同类型的文档包括相同的field。

  • 索引域:

用于搜索,搜索程序将从索引域中搜索一个一个词,根据词找到对应的文档。

将Document中的Field的内容进行分词,将分好的词创建索引,索引=Field域名:词

  • 倒排索引表

传统方法是先找到文件,如何在文件中找内容,在文件内容中匹配搜索关键字,这种方法是顺序扫描方法,数据量大就搜索慢。

倒排索引结构是根据内容(词语)找文档,倒排索引结构也叫反向索引结构,包括索引和文档两部分,索引即词汇表,它是在索引中匹配搜索关键字,由于索引内容量有限并且采用固定优化算法搜索速度很快,找到了索引中的词汇,词汇与文档关联,从而最终找到了文档。

   2、​​​​​​​​​​​​​​创建索引

创建索引的流程

                  

 

IndexWriter是索引过程的核心组件,通过IndexWriter可以创建新索引、更新索引、删除索引操作。IndexWriter需要通过Directory对索引进行存储操作。

Directory描述了索引的存储位置,底层封装了I/O操作,负责对索引进行存储。它是一个抽象类,它的子类常用的包括FSDirectory(在文件系统存储索引)、RAMDirectory(在内存存储索引)。

创建索引的代码实现:

@Test
	public void createIndex() throws Exception {
		// 采集数据
		BookDao dao = new BookDaoImpl();
		List<Book> list = dao.queryBooks();

		// 将采集到的数据封装到Document对象中
		List<Document> docList = new ArrayList<>();
		Document document;
		for (Book book : list) {
			document = new Document();
			// store:如果是yes,则说明存储到文档域中
			// 图书ID
			Field id = new TextField("id", book.getId().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 description = new TextField("description",
					book.getDescription(), Store.YES);

			// 将field域设置到Document对象中
			document.add(id);
			document.add(name);
			document.add(price);
			document.add(pic);
			document.add(description);

			docList.add(document);
		}

		// 创建分词器,标准分词器
		Analyzer analyzer = new StandardAnalyzer();

		// 创建IndexWriter
		IndexWriterConfig cfg = new IndexWriterConfig(Version.LUCENE_4_10_3,
				analyzer);
		// 指定索引库的地址
		File indexFile = new File("E:\\11-index\\hm19\\");
		Directory directory = FSDirectory.open(indexFile);
		IndexWriter writer = new IndexWriter(directory, cfg);

		// 通过IndexWriter对象将Document写入到索引库中
		for (Document doc : docList) {
			writer.addDocument(doc);
		}

		// 关闭writer
		writer.close();
	}
  • ​​​​​​​分词

Lucene中分词主要分为两个步骤:分词、过滤

分词:将field域中的内容一个个的分词。

过滤:将分好的词进行过滤,比如去掉标点符号、大写转小写、词的型还原(复数转单数、过去式转成现在式)、停用词过滤等,

停用词:单独应用没有特殊意义的词。比如的、啊、等,英文中的this is a the等等。

例如:要分词的内容是  "Lucene is a Java full-text search engine."

分词

Lucene

is

a

Java

Full

-

text

search

engine

.

 

过滤

去掉标点符号

Lucene

is

a

Java

Full

text

search

engine

去掉停用词

Lucene

Java

Full

text

search

engine

大写转小写

lucene

java

full

text

search

engine

 

如下图是语汇单元的生成过程:

从一个Reader字符流开始,创建一个基于Reader的Tokenizer分词器,经过三个TokenFilter生成语汇单元Token。

同一个域中相同的语汇单元(Token)对应同一个Term(词),它记录了语汇单元的内容及所在域的域名等,还包括来该token出现的频率及位置。

  • 不同的域中拆分出来的相同的单词对应不同的term。
  • 相同的域中拆分出来的相同的单词对应相同的term

 

  • ​​​​​​​使用luke工具查看索引以及相关的介绍

            双击lukeall-4.10.3.jar,打开

                 

                     

 

               

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值