用户注册



邮箱:

密码:

用户登录


邮箱:

密码:
记住登录一个月忘记密码?

发表随想


还能输入:200字

jun    -  云代码空间

—— 相信 ,梦

补充Lucene

2014-08-04|1406阅||

摘要:代码下次附上

Lucene 课程 第一天 核心语法

今天重点内容安排:

1、 索引在项目开发中使用 

2、 什么是lucene ? lucene能够做什么 ?

3、 lucene快速入门 

4、 分析索引内部结构原理 

5、 核心API 详细分析 

6、 基于lucene 结合 数据库实现 增删改查 

7、 lucene 使用注意问题 (索引优化  )

1.  lucene和搜索概述 

1.1.  搜索的历史 

搜索引擎: 对互联网上资源, 建立索引 ,加速搜索 

FTP资源、 网页资源 ---------- 音频、 视频、图片 建立索引 

Robot 网络机器人: 指在互联网上自动运行,指定特定任务一些程序 

Spider 网络爬虫 : 特殊网络机器人, 去互联网下载各种资源, 建立索引 

爬虫 是所有搜索引擎 基础 

1.2.  搜索技术的应用 

用途一: 应用软件 (word 、 window操作系统、 myeclipse 

用途二: 贴吧、 论坛、 博客 (对于文章的搜索 ) ---- 最常见应用 

用途三: 站内搜索 (京东 搜索商品、 51job 搜索招聘信息  ) --- 应用非常广

用途四: 专业搜索 (垂直领域搜索 818 工作网、 搜索引擎 baidugoogle  

信息搜索的过程 

第一步: 构建文本库  (对各种各样被搜索资源,提取文本信息 )

第二步: 对文本信息  建立索引 

第三步: 结合索引 完成搜索 

第四步: 对搜索结果排序显示 

1.3.  搜索系统中 最常用索引 --- 倒排索引 

传统线性查找一个10MBword文件,查找关键字如果在文档最后,大约3秒钟

倒排索引, 类似一本书的目录, 索引技术,是一项优化技术 ,提高查找速度 

2.  lucene的快速入门

2.1.  lucene概述 

问题: 什么是lucene ? 

Apache 提高 一套用于 进行全文信息检索java框架 (开源免费 )

Lucene 不是搜索引擎, 不可以直接当做软件或者产品使用 ,使用lucene 开发搜索引擎 

问题: 什么是全文检索 ? 

强调,对文本信息中每一个词,建立索引 ----- 全文检索(全文索引 )

Lucene 是全文索引 工具 

官网:http://lucene.apache.org/ 下载开发jar包 

企业使用lucene , 下载lucene (最新版本4.9 、 下载 solr (是基于lucene搜索服务器 )

课程: lucene3.x 

目录分析 

开发lucene 导入 lucene-core-3.6.2.jar 核心jar包 

contrib 目录存放 lucene开发依赖工具jar包  

开发项目 ,导入核心包 + contrib 依赖jar  

2.2.  快速入门 

导入jar 到工程 

第一步: 提取文本数据 --- 转换 Document对象 (被存放在索引库中 )

第二步: 结合lucene API Document 建立索引 

第三步: 结合luceneAPI 对索引库进行 查询 

2.2.1.  提取文本信息 --- 转换成Document对象 

将对象数据 转换为Document (不管是什么数据,lucene只能操作Document

需要使用Fieldable接口实现类 Field 构造

Field.Store 用来设置当前属性是否存放到索引库中 (搜索的结果)

Field.Index 用来设置当前属性是否索引库 建立索引  (搜索的过程)

2.2.2.  对Document数据 建立索引 

设置索引目录Directory

设置分词器Analyzer 

通过 IndexWriter 创建索引 

查看索引内容工具 --- luke 

 可执行jar文件 

通过 java jar命令运行 

问题: 为什么 id title、 content 都会被分词呢? 

设置 Index.ANALYZED 对内容进行分词 

如果设置 Index.NO 对属性,不会分词,建立词条 (用于搜索 

文档视图

如果设置 Store.YES , 在文档数据中就会存在属性 

如果设置Store.NO 属性就不会在Document中存储 (查询结果 

2.2.3.  基于索引进行查找 

搜索关键字 (用户输入)

设置索引目录Directory

设置分词器 Analyzer

搜索 获取Query 对象 (基于QueryParser分词搜索)

通过IndexSearcher对象,进行搜索 

搜索结果按照得分排名 TopDocs

获取每个文档得分对象 ScoreDocs 

3.  Lucene API 详细分析 

3.1.  lucene 包结构分析 

Lucene 没有很好内置分词器, 企业使用lucene 采用企业级分词器 (免费、 收费)

索引库建立 都基于Document 和 Field API 存储数据  

索引库建立 ,通过 IndexWriter API 完成

如果对搜索结果进行分词查找,使用QueryParser 

MultiFieldQueryParser 支持搜索多个字段 

索引库搜索, 基于Query抽象类对象完成, search包存放各种Query子类 

和索引存储相关API ,在store包, FSDirectory 将索引保存在文件目录 

3.2.  创建索引相关API

3.2.1.  Directory 索引目录 

在操作索引, 通常做法,将索引文件保存到硬盘 FSDirectory 

如果对搜索操作进行优化, 使用RAMDirectory 与 FSDirectory 结合方式 

3.2.2.  Analyzer 分词器

分词器,在对文本建立全文索引时,对目标内容进行分词的 

StandardAnalyzer lucene API内置 标准分词器, 对中文支持,每个字就是一个词 

(企业级分词器 : IK分词器、 Paoding 分词器   )

IK 分词器使用 


下载 IKAnalyzer2012_u6.zip 最新版 


使用IK分词器,在项目导入 IKAnalyzer.jar 

核心配置文件 IKAnalyzer.cfg.xml (扩展词典、 停用词典)

扩展词典 ,对IK内置词典进行扩展 

停用词典 ,有些词没有必要建立索引 啊、的、了、着 (不会出现在索引库)

默认停用词典stopword.dic



使用IK分词器建立索引 


3.2.3.  Document 文档对象 和Field 属性 

在实际应用中, 各种数据来源,提取出文本信息 --- 转换成Document对象 

参考资源 : Lucene&Java精华版 第三章 





name 属性: 属性名称 ,用于搜索、 用于获取结果

value 属性: 属性值, 被分词建立索引, 保存document中,作为查询结果 

Store.YES StoreNO : document中是否存储这个属性,如果不存储,查询结果中没有该属性

Index.NO: 这个属性不建立索引 

Index.ANALYZED:分词建立索引 (使用分词器)

Index.NOT_ANALYZED :不分词建立索引 (将属性value 完整作为一个词条 term

norm 作为分词参数, 影响得分,保存document中 ,如果内容分词越多, norm值越低 , 算分越低 )

Index.ANALYZED_NO_NORMS:分词索引, 在document中不保存 norm信息 

Index.NOT_ANALYZED_NO_NORMS:不分词索引,在document中不保存 norm信息

NO_NORMS 存放方式 更加高效 

案例: 如何选择StoreIndex 


思考: 要不要根据书号查询图书 ?  (要不要对书号进行索引

如果需要书号查询, 那么是否要求用户输入完整的书号 ? (如果索引,要不要分词 )

在查询结果中需不需要显示书号? (要不要将属性存储到Document )

3.2.4.  IndexWriterConfig 生成索引配置对象 


可以设置IndexWriter的打开模式 

OpenMode.APPEND 在原有索引库 ,增加索引 (默认)

OpenMode.CREATE 覆盖原来的索引库 


CREATE 使用场景, FSDirectory 结合 RAMDirectory优化,使用 

3.2.5.  IndexWriter 生成索引 

调用 IndexWriteraddDocument(Document) 添加新的索引 




IndexWriter操作索引库, 添加锁文件 

 当前其它线程,通过IndexWriter操作索引库,无法操作

org.apache.lucene.store.LockObtainFailedException: Lock obtain timed out: NativeFSLock@D:\work\sh_javaee20140513\lucene3_day1\index\write.lock

所以在实际开发中,如果多线程,同时操作索引库, 建立工具类, 提供唯一IndexWriter !


在程序运行时,多个线程获取到 同一个IndexWriter 对象 

3.3.  搜索索引相关API

3.3.1.  搜索需要获取Query对象 

问题: 如何根据搜索内容建立 Query 对象 

第一种: QueryParser 分词建立Query对象 ,根据输入内容进行分词,比较词条,只要有一个词条满足, 返回搜索结果 

解析分词搜索 .  QueryParser 只支持对一个字段搜索 !!!! )

 指定多个字段搜索 

第二种 : TermQuery 直接对词条搜索 

直接搜索索引库词条 !!!  

Term 作为完成词条搜索,不会被分词 

3.3.2.  对于搜索结果操作 

3.3.3.  将IndexSearcher获取放入工具类 

IndexSearcher 和 IndexWriter 不同 

IndexWriter 操作索引库 会加锁 

IndexSearcher 不会加锁,多线程同时使用 

IndexSearcher 对象不要定义static 全局变量, 因为每次返回 IndexSearcher 加载最新当前索引库, 如果返回同一个对象,造成索引库更新后,searcher内容没有更新 ! 

4.  索引库如何和数据库结合使用 

问题: 

1、 一个软件 ,数据保存到数据库中, 索引库中存放什么? 

2、 索引库和数据库 在软件中 是怎样的关系?

3、 软件项目中 为什么要使用索引技术 ? 

4、 数据库中没有索引吗?  

以论坛为例, 论坛需要发帖,帖子信息保存在数据库中 ,数据库可以对帖子列 进行索引 (数据库不支持全文索引 ) ----- 当执行帖子搜索 执行 content like ? , like 模糊查询无法使用数据库内部索引 , 导致大规模数据模糊搜索 性能非常差 ---------- lucene全文索引库解决这类问题 (建立词条,相同词合并 )

用户在开发中, 先查找索引库词条, 获取基本信息 (业务显示需要 ), 当点击详情查找数据库获取详细信息 (可以在索引库只存放数据记录id , 查找索引库,获取这些id ,再通过 id 查找数据库 )

保证索引库和数据库数据同步问题!!! 

如何做到同步?? 在DAO 对数据进行增删改查同时,同时操作索引库 

4.1.  基于hibernate 实现article 增加、修改、删除

导入hibernate jar包, 导入配置文件 ,修改jdbc参数 

JPA注解

Hbm映射

Service 

DAO 

4.2.  在hibernate增删改同时操作索引库 

操作数据库记录同时,操作索引库 

建立索引


删除索引

修改索引 


4.3.  结合索引库完成like模糊搜索 

业务层 先查找索引库 获取记录id ,再查找数据库 获取记录 

业务层代码 : 


ArticleIndexDAO 先查找索引库,获取记录id 


ArticleDAO 再根据id 查找数据库,获取Article对象 


================ lucene 索引优化, 针对大数据 like 模糊搜索 

5.  索引库调优 

5.1.  合并因子调优 


如果mergeFactor 设置过大, 索引文件过多 

如果 mergeFactor 设置过小, 单个索引文件 体积过大 


5.2.  使用RAMDirectory优化 

默认操作索引库, 都是操作硬盘系统索引文件, 每次写入索引,在硬盘新建文件,每次读取索引,读取硬盘索引文件 


在第一次操作索引库, 将硬盘中索引内容,都加载到内存中, 以后每次操作,都针对内容索引库进行, 在特定时间 (定时、 虚拟机退出), 将内存中索引库 回写到硬盘 

问题: 如何将硬盘中索引文件读取到内存中 ?


问题 : 如何将内存中索引库,回写到硬盘上? 


完整代码 


6.  补充: Hibernate Search 框架 

在使用lucene索引库, 结合数据库方式 

在增加、修改、删除 数据时  将数据库和索引库 进行同步 

like模糊搜索 时, 先查询索引库,获取记录id ,再查找数据库 

什么是hibernate search ? 

Hibernate Search是在apache Lucene的基础上建立的主要用于Hibernate的持久化模型的全文检索工具


下载 hibernate search 

3.x 依赖hibernate3 lucene3.x 

4.x 依赖hibernate4 lucene3.x 


导入 hibernate-search-3.4.2.Final.jar (依赖hibernatelucene 


第一步: 导入jar包,在hibernate 配置文件中 配置索引库位置 

使用search后,索引由hibernate search 创建 


第二步: 配置对哪些数据进行索引 


@Indexd 对实体数据进行索引

@DocumentId 主键字段

@Field 属性进行索引,默认分词索引,不存储

@Analyzer 指定分词器 

hibernate 执行 增加、修改、删除, hibernate search 会自动 同步索引库 !

使用hibernate search 完成搜索 


Hibernate search 封装,先查询索引库,获取id ,再查询数据库过程 !


顶 1踩 1收藏
文章评论
    发表评论

    个人资料

    • 昵称: jun
    • 等级: 资深程序员
    • 积分: 1523
    • 代码: 94 个
    • 文章: 24 篇
    • 随想: 0 条
    • 访问: 7 次
    • 关注

    最新提问

      站长推荐