OSChina是如何处理索引更新问题的

来源:转载


一般使用 Lucene 来做全文搜索时,都会碰到这样一个问题,什么时候创建、更新或者删除索引。

假设是发帖子吧,如果一发贴就即时写入索引,好处是索引及时,但这会引起索引库被锁的问题,因为同一个时间可能很多人都在发帖,更新和删除都是同样的问题存在。

还有另外一个方法是后台定时将新增的帖子写入索引库,这种可以避免索引库被锁的问题,不过刚发的帖子就没法被索引到(这个不是大问题,一般都可以接受),但是对一些帖子的修改和删除,处理起来就比较麻烦,你不知道哪些帖子被改了,或者被删了。

OSChina 现在的做法是引入一个 LuceneTask 类,代表要执行的一次索引任务,这个任务可以是添加、修改或者删除,每次新增帖子、修改帖子或者删除帖子时,只是对应的往数据库的一个表里写入一条 LuceneTask 数据即可。而后台通过 crontab 每隔一分钟从 LuceneTask 表中检索出待处理的索引任务记录,处理完毕后将该记录的状态改为已完成。

LuceneTask 类的代码如下:

?123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115packagenet.oschina.search; importjava.util.Date; importmy.db.QueryHelper;importmy.search.SearchEnabled;importnet.oschina.beans.Article;importnet.oschina.beans.Blog;importnet.oschina.beans.News;importnet.oschina.beans.Pojo;importnet.oschina.beans.Project; /** * Lucene索引更新任务 * @author Winter Lau * @date 2010-1-4 下午04:57:47 */publicclassLuceneTask extendsPojo {         publicfinalstatictransientbyteOPT_ADD      = 0x01;    publicfinalstatictransientbyteOPT_UPDATE   = 0x02;    publicfinalstatictransientbyteOPT_DELETE   = 0x04;         /**     * 返回对应的对象资料     * @return     */    publicSearchEnabled object(){        switch(obj_type) {        caseTYPE_PROJECT:            return(Project)Project.INSTANCE.Get(obj_id);        caseTYPE_NEWS:            return(News)News.INSTANCE.Get(obj_id);        caseTYPE_THREAD:            returnnet.oschina.beans.Thread.Read(obj_id);        caseTYPE_ARTICLE:            return(Article)Article.INSTANCE.Get(obj_id);        caseTYPE_BLOG:            return(Blog)Blog.INSTANCE.Get(obj_id);        }        returnnull;    }         publicvoidafterBuild(){        String sql = "UPDATE osc_lucene_tasks SET status=1,handle_time=NOW() WHERE id=?";        QueryHelper.update(sql, getId());    }         publicstaticvoidadd(longobj_id, byteobj_type) {        newLuceneTask(obj_id, obj_type, OPT_ADD).Save();    }     publicstaticvoidupdate(longobj_id, byteobj_type) {        newLuceneTask(obj_id, obj_type, OPT_UPDATE).Save();    }     publicstaticvoiddelete(longobj_id, byteobj_type) {        newLuceneTask(obj_id, obj_type, OPT_DELETE).Save();    }         publicLuceneTask() {    }     publicLuceneTask(longobj_id, byteobj_type, byteopt) {        this.obj_id = obj_id;        this.obj_type = obj_type;        this.opt = opt;        this.status = 0;    }     privatelongobj_id;    privatebyteobj_type;    privatebyteopt;    privatebytestatus;    privateDate create_time;    privateDate handle_time;         publiclonggetObj_id() {        returnobj_id;    }    publicvoidsetObj_id(longobj_id) {        this.obj_id = obj_id;    }    publicbytegetObj_type() {        returnobj_type;    }    publicvoidsetObj_type(byteobj_type) {        this.obj_type = obj_type;    }    publicbytegetOpt() {        returnopt;    }    publicvoidsetOpt(byteopt) {        this.opt = opt;    }    publicbytegetStatus() {        returnstatus;    }    publicvoidsetStatus(bytestatus) {        this.status = status;    }    publicDate getCreate_time() {        returncreate_time;    }    publicvoidsetCreate_time(Date create_time) {        this.create_time = create_time;    }    publicDate getHandle_time() {        returnhandle_time;    }    publicvoidsetHandle_time(Date handle_time) {        this.handle_time = handle_time;    }     }

其中 obj_id 代表帖子的编号,obj_type 代表帖子的类型,可以是帖子,可以是新闻,也可以是软件。

这个结构其实挺适合 Lucene 实现索引的各类项目,所以贴出来分享一下。

红薯
发帖于 5年前
14回/3998阅标签:Lucene 精华
  • 举报 
  • | 分享到
0收藏(47)

按默认排序  显示最新评论  共有14个评论 (最后回答: 1年前)

    0
  • chen辉1年前没有完整源码,小白表示看的云里雾里!评论(0)| 引用此评论|举报 (2013-11-01 14:00)0
  • 梁某某2年前红薯您好,我现在一个项目需要用到lucene,我想在请教您一下, lucene更新索引的效率到底如何,比如:我目前数据库有30万,数据,估计从数据库查询取数据到创建索引完成会要多久呢?不考虑服务器性能方面的问题!评论(0)| 引用此评论|举报 (2013-04-27 21:59)0
  • 阿桂爱清净2年前

    好像还有个机制就是增加或者更新的索引先写到内存里,每隔一定的时候与硬盘中索引合并

    这样可以做到及时索引

    但是如果出现down机了 内存中的索引就over了

    评论(0)| 引用此评论|举报 (2012-10-28 21:04)0
  • 林毅文2年前真的顶一下。评论(0)| 引用此评论|举报 (2012-10-23 16:45)0
  • Mr_Idk3年前关注... 
    评论(0)| 引用此评论|举报 (2012-09-07 20:40)0
  • 颜磊3年前这个想法,见过,哈哈



分享给朋友:
您可能感兴趣的文章:
随机阅读: