Lucene实现索引数据的增删改查
来源:互联网 发布:网页设计软件培训 编辑:程序博客网 时间:2024/06/05 20:23
lucene是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎,部分文本分析引擎.它提供了一个简单却强大的应用程式接口,能够做全文索引和搜寻。在java开发环境里lucene是一个成熟的免费开源工具。就其本身而言,lucene是很受欢迎的免费java资讯检索程式库。
当前版本为4.2, 官方网站: http://lucene.apache.org/
在全文索引工具中,都是由3部分组成
1.索引部分
2.分词部分
3.搜索部分
建立索引的步骤
1.创建directory
2.创建indexwriter
3.创建document对象
4.为document添加field
/** * description: 建立索引 * */public void createindex(){ indexwriter indexwriter = null; try { //1.创建directory directory directory = new ramdirectory(); //在内存中建立索引 //2.创建indexwriter indexwriterconfig indexwiterconfig = new indexwriterconfig(version.lucene_36, new standardanalyzer(version.lucene_36)); indexwriter = new indexwriter(directory, indexwiterconfig); //3.创建document对象 document document = new document(); //4.为document添加field file filepath = new file("luence/example"); for(file file: filepath.listfiles()){ //为该文件夹下的所有文件建立索引 document = new document(); //传入文件内容 document.add(new field("content",new filereader(file))); //传入文件名 document.add(new field("filename", file.getname(),field.store.yes,field.index.not_analyzed)); //传入文件路径 document.add(new field("path",file.getabsolutepath(),field.store.yes,field.index.not_analyzed)); //5.通过indexwriter添加文档到索引中 indexwriter.adddocument(document); } } catch (exception e) { e.printstacktrace(); }finally{ if(indexwriter!=null){ try { indexwriter.close(); } catch (exception e) { e.printstacktrace(); } } }}
上面实例中在内存中创建索引.也可以在硬盘上创建索引: directory directory2 = fsdirectory.open(new file("f:/luence/index"));
//在硬盘上的f:/luence/index下建立索引
搜索操作的步骤:
1.创建directory
2.创建indexreader
3.根据indexreader创建indexsearcher
4.创建搜索的query
5.根据searcher搜索并且返回topdocs
6.根据topdocs获取scoredoc对象
7.根据seacher和scoredoc对象获取具体的document对象
8.根据document对象获取需要的值
9.关闭indexreader
public void searcher(){ try { //1.创建directory 在硬盘上的f:/luence/index下建立索引 directory directory = fsdirectory.open(new file("f:/luence/index")); //2.创建indexreader indexreader indexreader = indexreader.open(directory); //3.根据indexreader创建indexsearcher indexsearcher indexsearcher = new indexsearcher(indexreader); //4.创建搜索的query //创建parser来确定要搜索文件的内容,第二个参数表示搜索的域, 实例中为"content",表示在内容中查找 queryparser queryparser = new queryparser(version.lucene_36,"content",new standardanalyzer(version.lucene_36)); //创建query,表示搜索域为content中包含java关键字的文档 query query = queryparser.parse("java"); //搜索包含关键字java的信息 //5.根据searcher搜索并且返回topdocs //查询,第二个参数表示显示前10条记录 topdocs topdoc = indexsearcher.search(query, 10); //6.根据topdocs获取scoredoc对象 scoredoc[] scoredocs = topdoc.scoredocs; for(scoredoc scoredoc : scoredocs){ //7.根据seacher和scoredoc对象获取具体的document对象 document document = indexsearcher.doc(scoredoc.doc); //8.根据document对象获取需要的值 system.out.println(document.get("filename") + "[" + document.get("path") + "]"); } //9.关闭indexreader indexreader.close(); } catch (exception e) { // todo: handle exception }}
文档document和域field的关系
文档document相当于关系表中的每一条记录,域相当于表中的每一个字段,先创建文档,之后为文档添加域.
域存储选项和域索引选项,均需要在域添加的时候设置
存储域选项
field.store.yes表示把这个域中的内容完全存储到文件中,方便进行文本的还原
field.store.no表示把这个域中的内容不存储到文件中,但是可以被索引,此时内容无法还原(即无法document.get());
索引域选项
field.index.analyzed:进行分词和索引,适用于标题和内容等
field.index.not_analyzed:进行索引,但是不进行分词,像身份证号,姓名,id等,适用于精确索索
field.index.analyzed_no_norms:进行分词但是不存储norms信息,这个norms中包括了创建索引的时间和权值等信息
field.index.not_analyzed_no_norms:即不进行分词也不存储norms信息
field.index.no:不进行索引
最佳实践
field.index.not_analyzed_no_norms, field.store.yes标识符(主键,文件名),电话号码,身份证号,姓名,日期
field.index.analyzed, field.store.yes文档标题和摘要
field.index.analyzed, field.store.no文档正文
field.index.no,field.store.yes文档类型,数据库主键(不进行索引)
field.index.not_analyzed,field.store.no 隐藏关键字
删除文档操作
public void delete(){ indexwriter indexwriter = null; try { indexwriterconfig indexwriterconfig = new indexwriterconfig(version.lucene_36,new standardanalyzer(version.lucene_36)); indexwriter = new indexwriter(directory, indexwriterconfig); //参数是一个选项,可以是一个query,也可以是一个term,term是一个精确查找的值 //此时删除的文档并不会完全被删除,而是存储在一个回收站中,可以恢复 //使用reader可以有效的恢复取到的文档数 indexwriter.deletedocuments(new term("id","1")); } catch (exception e) { e.printstacktrace(); }finally{ if(indexwriter!=null){ try { indexwriter.close(); } catch (exception e) { e.printstacktrace(); } } } }
indexwriter.deletedocuments()文档并不会完全被删除,而是存储在一个回收站中,我们可以编写查询类来进行查询
public void query(){ try { indexreader indexreader = indexreader.open(directory); system.out.println("存储的文档数:" + indexreader.numdocs()); system.out.println("总存储量:" + indexreader.maxdoc()); system.out.println("被删除的文档:" + indexreader.numdeleteddocs()); } catch (exception e) { e.printstacktrace(); } }
测试程序
luenceindex luence = new luenceindex("f:/luence/index"); luence.index(); system.out.println("===== 首次建立索引后进行查询 ====="); luence.query(); luence.delete(); system.out.println("===== 调用删除操作后进行查询 ====="); luence.query();
分析程序运行结果
===== 首次建立索引后进行查询 =====
存储的文档数:5
总存储量:5
被删除的文档:0
===== 调用删除操作后进行查询 =====
存储的文档数:4
总存储量:5
被删除的文档:1
使用indexreader可以有效的恢复删除到回收站的文档
public void recovery(){ try { indexreader indexreader = indexreader.open(directory,false); //通过indexreader进行恢复,恢复时,必须把indexreader的只读(readonly)设置为false indexreader.undeleteall(); indexreader.close(); } catch (exception e) { e.printstacktrace(); } }
如果要清空回收站中的内容,需要使用indexwriter中的forcemergedeletes()方法
public void forcedelete(){ indexwriter indexwriter = null; try { indexwriterconfig indexwriterconfig = new indexwriterconfig(version.lucene_36,new standardanalyzer(version.lucene_36)); indexwriter = new indexwriter(directory, indexwriterconfig); indexwriter.forcemergedeletes(); } catch (exception e) { e.printstacktrace(); }finally{ if(indexwriter!=null){ try { indexwriter.close(); } catch (exception e2) { e2.printstacktrace(); } } }}
这次测试
public static void main(string[] args) { luenceindex luence = new luenceindex("f:/luence/index"); luence.index(); system.out.println("===== 首次建立索引后进行查询 ====="); luence.query(); luence.delete(); system.out.println("===== 调用删除操作后进行查询 ====="); luence.query(); luence.forcedelete(); system.out.println("===== 清空回收站内容后进行查询 ====="); luence.query(); }
运行结果
===== 首次建立索引后进行查询 =====
存储的文档数:5
总存储量:5
被删除的文档:0
===== 调用删除操作后进行查询 =====
存储的文档数:4
总存储量:5
被删除的文档:1
===== 清空回收站内容后进行查询 =====
存储的文档数:4
总存储量:4
被删除的文档:0
luence更新操作
public void update(){ indexwriter indexwriter = null; try { indexwriterconfig indexwriterconfig = new indexwriterconfig(version.lucene_36,new standardanalyzer(version.lucene_36)); indexwriter = new indexwriter(directory, indexwriterconfig); //luence并没有提供更新,这里的更新操作其实是先删除再添加的操作合集 document document = new document(); document.add(new field("id","updateid",field.store.yes,field.index.not_analyzed_no_norms)); document.add(new field("email","updateemail",field.store.yes,field.index.not_analyzed)); document.add(new field("content","updatecontent",field.store.no,field.index.analyzed)); document.add(new field("name","updatename",field.store.yes,field.index.not_analyzed_no_norms)); //更新id为2的数据 indexwriter.updatedocument(new term("id","2"), document); } catch (exception e) { e.printstacktrace(); }finally{ if(indexwriter!=null){ try { indexwriter.close(); } catch (exception e) { e.printstacktrace(); }
- Lucene实现索引数据的增删改查
- lucene索引的增删改查
- 02-lucene索引的增删改查
- lucene索引的增删改查/lucene索引维护
- lucene索引库的增删改查操作
- Lucene索引的增删改查和二次检索
- lucene(二) 索引的创建、增删改查
- Lucene之索引的增删改查-yellowcong
- Lucene使用(二)索引的增删改查
- lucene 的 增删改查
- Lucene的增删查改
- lucene的增删改查
- mybatis ---- 实现数据的增删改查
- html实现数据的增删查改
- MyBatis实现数据的增删查改
- Mybatis实现数据的增删改查
- 搜索学习入门--Lucene初体验(Lucene索引的增删改查)
- lucene增删改查
- 有bug的KMP
- 共用体的应用(判断端序)
- 使用python调用java-jpype
- springboot注解
- docker安装与实现myql主从复制
- Lucene实现索引数据的增删改查
- 重载Overload 重写
- memcpy的用法
- jQuery 扩展,将复杂form表单转成json对象serializeJson
- Android四大组件之Activity (启动模式)
- java抽象类和接口
- spring 文件资源操作和 Web 相关工具类
- sizeof()用法汇总
- JS获取验证码后倒计时不受页面刷新及关闭影响