更新操作如下:

注意:通过lukeall-1.0.0.jar 查看软件,我们可以看到,更新其实是先删除在插入, 前面我们知道索引库中有两部分的内容组成,一个是索引文件,另一个是目录文件, 目前我们更新, 只是真对Document, 但是Term部分并没有同步, 所以等会需要优化索引库即可

 // 把商品信息添加到索引库中
public void updateGoods(Goods goods){
// 创建一个indexWriter
IndexWriter indexWriter=null;
try {
indexWriter=new IndexWriter(Configuraction.getDirectory(),Configuraction.getAnalyzer(),MaxFieldLength.LIMITED);
/*
* 先删除文档,在追加文档
* Term: 删除文档的条件,一般来说我们都是根据主键删除
* doc:追加的新文档
* */
indexWriter.updateDocument(new Term("gid",goods.getGid().toString()),DocumentUtil.GoodsToDocument(goods));
// 提交
indexWriter.commit();
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
}finally{
try {
// 更新操作的时候,原来的document已经删除,但是原来term并没有同步
// 需要同步:otimize:让term与document同步
indexWriter.optimize();
indexWriter.close();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
} }

注意 :

注意更新操作和删除操作:都要进行optimize()方法优化,否则只会更新索引数据,不会更新索引目录. 以后可以把此操作放到独立的线程中定时执行

删除操作

     public void deleteGoods(int gid){
// 创建一个indexWriter
IndexWriter indexWriter=null;
try {
indexWriter=new IndexWriter(Configuraction.getDirectory(),Configuraction.getAnalyzer(),MaxFieldLength.LIMITED);
indexWriter.deleteDocuments(new Term("gid",gid+""));
// 提交
indexWriter.commit();
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
}finally{
try {
indexWriter.optimize();
indexWriter.close();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
} }

分页查询

 public List<Goods> query(String gname,int currentPage){
int size=5; // 2*5--->10条
List<Goods> goodsList=new ArrayList<Goods>();
// 创建查询工具类
IndexSearcher indexSearcher=null;
try {
QueryParser parse=new QueryParser(Version.LUCENE_30,"gname",Configuraction.getAnalyzer());
// 解析要查询的关键字:返回的是Query类型
Query query=parse.parse(gname);
indexSearcher=new IndexSearcher(Configuraction.getDirectory());
// indexSearch做查询操作: n 用户期望查询结果数,后面做分页使用
// 0 1 2 3 4 [5 6 7 8 9]
TopDocs topDocs=indexSearcher.search(query,currentPage*size);
/*
* TopDocs:
* totalHits: 实际查询到的结果数
* scoreDocs[]: 存储了所有符合条件的document 编号
* */
System.out.println("用户期待的数:" + currentPage*size);
System.out.println("索引库实际拥有结果数为:" + topDocs.totalHits);
// 存储的是document在lucenen中的逻辑编号
ScoreDoc[] docs=topDocs.scoreDocs; //[0]=0 [1]=1
System.out.println("真实拿出来了文档编号数" + docs.length);
/*
* ScoreDoc:
* doc: 文档逻辑编号
* score: 当前文档得分
*
* */
for(int i=(currentPage-1)*size;i<docs.length;i++){
//System.out.println("文档的编号:" + docs[i].doc);
//System.out.println("此文档的得分:" + docs[i].score);
// 通过文档的编号获取真正的文档
Document doc=indexSearcher.doc(docs[i].doc);
goodsList.add(DocumentUtil.DocumentToGoods(doc));
}
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
return goodsList;
}

分页的原理分析:

Search(query,10000),和Search(query,1)都不会影响topDocs.totalHits这个结果, 这个结果是Lucene索引库命中率的次数(也就是命中的Tearm的数量)那么可能会出现 totalHits大或者currentPage * PAGE_SIZE大的情况. 所以真正截取的时候,选最小的.int endNuM = Math.min(topDocs.totalHits, currentPage * PAGE_SIZE);而且分页的话,不是从开始处,开始所以真正的代码为:for (int i = (currentPage - 1) * PAGE_SIZE; i < endNuM; i++)

IndexWriter存在的问题

IndexWriter: 则必须要用单态模式独占.因为每一个Writer都需要lock文件,IndexWriter本身是操作类,支持多线程,所以一个全局的IndexWriter即可

 @Test
public void testIndexWriter()throws Exception{
IndexWriter indexWriter = new IndexWriter(Configuraction.getDirectory(),Configuraction.getAnalyzer(), MaxFieldLength.LIMITED);
IndexWriter indexWriter2 = new IndexWriter(Configuraction.getDirectory(),Configuraction.getAnalyzer(), MaxFieldLength.LIMITED);
}

异常信息如下:

org.apache.lucene.store.LockObtainFailedException: Lock obtain timed out: NativeFSLock@D:\workspace\lucene3.0\indexData\write.lock

IndexWriter优化

 package cn.index;

 import java.io.IOException;

 import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriter.MaxFieldLength;
import org.apache.lucene.search.IndexSearcher; /*
* 把indexWriter:设置全局唯一的,项目只负责使用, 由LuceneUtil负责创建和销毁
*
* */ public class LuceneUtil { private static IndexWriter indexWriter = null;
// 每一个indexSearcher在创建的时候就给索引库拍了一个快照,后面对索引库更新的操作都不能识别
// 也类MYSQL:隔离级别3: 可重复读
private static IndexSearcher indexSearcher=null; public static IndexSearcher getIndexSearcher() {
// 判断是否有IndexSearcher如果没有则创建一个
if(indexSearcher==null){
synchronized(LuceneUtil.class){
if(indexSearcher==null){
try {
indexSearcher=new IndexSearcher(Configuraction.getDirectory());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
new RuntimeException(e);
}
}
}
}
return indexSearcher;
} public static IndexWriter getIndexWriter() {
// 获取IndexWriter的时候说明要操作索引库,此时关闭前面的indexSearch
// indexSearcher
closeIndexSearch(indexSearcher);
// 把全局变量设置为null
indexSearcher=null;
return indexWriter;
} private static void closeIndexWriter(IndexWriter indexWriter){
if(indexWriter!=null){
try {
indexWriter.optimize();
indexWriter.close();
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
} private static void closeIndexSearch(IndexSearcher indexSearcher){
if(indexSearcher!=null){
try {
indexSearcher.close();
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
} static {
try {
// 加载LuceneUtil执行indexWriter创建
indexWriter = new IndexWriter(Configuraction.getDirectory(),
Configuraction.getAnalyzer(), MaxFieldLength.LIMITED);
// 程序关闭的时候要释放资源
Runtime.getRuntime().addShutdownHook(new Thread(){
public void run(){
System.out.println("----run-----");
// 程序结束的时候关闭indexWriter
closeIndexWriter(indexWriter);
}
});
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
}

Lucene 更新、删除、分页操作以及IndexWriter优化的更多相关文章

  1. 解决lucene更新删除无效的问题

    个人博客 地址:http://www.wenhaofan.com/article/20180921233809 问题描述 在使用deleteDocuments,updateDocument方法根据id ...

  2. lucene两个分页操作

    基于lucene两个分页: lucene3.5查询方式(每次查询所有记录,然后取当中部分记录.这样的方式用的最多),lucene官方的解释:因为我们的速度足够快. 处理海量数据时.内存easy内存溢出 ...

  3. Android Sqlite数据库执行插入查询更新删除的操作对比

    下面是在Android4.0上,利用Sqlite数据库的insert,query,update,delete函数以及execSql,rawQuery函数执行插入,查询,更新,删除操作花费时间的对比结果 ...

  4. lucene之排序、设置权重、优化、分布式搜索(转)

    lucene之排序.设置权重.优化.分布式搜索(转) 1. 基本应用 using System;using System.Collections.Generic;using System.Text;u ...

  5. 前端性能优化--为什么DOM操作慢? 浅谈DOM的操作以及性能优化问题-重绘重排 为什么要减少DOM操作 为什么要减少操作DOM

    前端性能优化--为什么DOM操作慢?   作为一个前端,不能不考虑性能问题.对于大多数前端来说,性能优化的方法可能包括以下这些: 减少HTTP请求(合并css.js,雪碧图/base64图片) 压缩( ...

  6. EasyUI整合SpringBoot,Spring Data对数据的分页操作

    EasyUI的用法可以看中文官网,看插件是如何使用的 EasyUI中文官网 前端页面 <table id="dg" title="My Users" cl ...

  7. DOM操作的性能优化

    DOM操作的真正问题在于 每次操作都会出发布局的改变.DOM树的修改和渲染. React解决了大面积的DOM操作的性能问题,实现了一个虚拟DOM,即virtual DOM,这个我们一条条讲. 所以关于 ...

  8. 传统servelt项目之分页操作

    需求说明: • 演示最终分页效果 • 提供分页素材     • 分页的作用 • 数据量大,一页容不下 • 后台查询部分数据而不是全部数据 • 降低带宽使用,提高访问速度     • 分页的实现思路 • ...

  9. UniqueMergeTree:支持实时更新删除的 ClickHouse 表引擎

    UniqueMergeTree 开发的业务背景 首先,我们看一下哪些场景需要用到实时更新. 我们总结了三类场景: 第一类是业务需要对它的交易类数据进行实时分析,需要把数据流同步到 ClickHouse ...

随机推荐

  1. Spark日志级别修改

    摘要 在学习使用Spark的过程中,总是想对内部运行过程作深入的了解,其中DEBUG和TRACE级别的日志可以为我们提供详细和有用的信息,那么如何进行合理设置呢,不复杂但也绝不是将一个INFO换为TR ...

  2. 给定1-a的随机数生成器,产生1-b的随机数生成器

    转自http://www.code123.cc/959.html 先给出一个例子,后面会有扩展 题目 给你一个能生成1到5随机数的函数,用它写一个函数生成1到7的随机数. (即:使用函数rand5() ...

  3. MySQL,sqlalchemy

    Mariadb 数据库是一堆表的集合 主键 外键 索引 安装: Centos7 [root@host]# mysqladmin -u root password "new_password& ...

  4. vim初级命令

    命令 说明 光标移动   h 左 l(小写L) 右 j 下 k 上 w 移动到下一个单词 b 移动到上一个单词     插入   i 在当前光标处进行编辑 I(大写i) 在行首插入 A 在行末插入 a ...

  5. idea配置mave

    历史信息为同意管理,本博客是从小号迁移而来,‘会飞的鱼la’已经注销 准备工作1.下载idea并激活http://idea.iteblog.com/key.php 2.下载mavenhttp://mi ...

  6. hdu6162 Ch’s gift

    地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=6162 题目: Ch’s gift Time Limit: 6000/3000 MS (Java ...

  7. 对Spring Ioc 以及DI的精彩理解

    转:http://blog.csdn.net/cyjs1988/article/details/50352916 学习过spring框架的人一定都会听过Spring的IoC(控制反转) .DI(依赖注 ...

  8. imx6q android 添加开机启动脚本

    1.在xx/out/target/product/sabresd_6dq/root/init.rc中添加以下内容 ========================================== ...

  9. PHP(Mysql/Redis)消息队列的介绍及应用场景案例

    在进行网站设计的时候,有时候会遇到给用户大量发送短信,或者订单系统有大量的日志需要记录,还有做秒杀设计的时候,服务器无法承受这种瞬间的压力,无法正常处理,咱们怎么才能保证系统正常有效的运行呢?这时候我 ...

  10. Vue数据绑定失效

    首先,我们得明白Vue数据响应的原理: 以对象为例:当把一个JavaScript对象传给Vue实例的data选项时,Vue将遍历此对象所有的属性,并使用Object.defineProperty把这些 ...