`

lucene增量索引的简单实现

阅读更多
用lucene来建立搜索程序,在检索的时候效率大大的提高了,但是却以建立索引为代价,建立索引本身就是个耗内存大、时间长的过程(数据量比较大,数据少何必用lucene来建立全文检索,个人拙见),从而索引的建立就是个瓶颈,如果我们建立好索引,然后每次更新数据后重新建立索引,无疑是不合理的,为什么不能在原先索引文件的基础上再把新更新的加在上面呢?增量索引就是在建完索引的后,将数据库的最后一条记录的ID存储起来,下次建立时候将这个ID拿到,从而可以把更新的数据拿到,并把这些更新数据的索引文件加在原先的索引文件里面,下面来看个简单的例子
数据库有两个字段id和title,话不多说,直接上代码,一看便知
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexWriter;

public class Index {

    public static void main(String[] args) {
        try {
             Index index = new Index();
             String path = "d:\\index";//索引文件的存放路径
             String storeIdPath = "d:\\storeId.txt";//存储ID的路径
             String storeId ="";
             storeId = index.getStoreId(storeIdPath);
             ResultSet rs = index.getResult(storeId);
             index.indexBuilding(path, storeIdPath, rs);
             storeId = index.getStoreId(storeIdPath);
             System.out.println(storeId);//打印出这次存储起来的ID
         } catch (Exception e) {
             e.printStackTrace();
         }
     }
    
    public ResultSet getResult(String storeId) throws Exception{
         Class.forName("com.mysql.jdbc.Driver").newInstance();
         String url = "jdbc:mysql://localhost:3306/ding";
         String userName = "root";
         String password = "ding";
         Connection conn = DriverManager.getConnection(url,userName,password);
         Statement stmt = conn
             .createStatement();
         ResultSet rs = stmt
             .executeQuery("select * from newitem where id > '"+storeId+"'order by id");
        return rs;
     }

    public boolean indexBuilding(String path,String storeIdPath, ResultSet rs) {// 把RS换成LIST原理一样

        try {
             Analyzer luceneAnalyzer = new StandardAnalyzer();
            // 取得存储起来的ID,以判定是增量索引还是重新索引
            boolean isEmpty = true;
             try { 
                 File file = new File(storeIdPath);
                if (!file.exists()) {
                     file.createNewFile();
                 }
                 FileReader fr = new FileReader(storeIdPath);
                 BufferedReader br = new BufferedReader(fr);                 
                if(br.readLine()!= null) {
                     isEmpty = false;
                  }
                  br.close();
                  fr.close(); 
                 } catch (IOException e) { 
                    e.printStackTrace();
               }

             IndexWriter writer = new IndexWriter(path, luceneAnalyzer, isEmpty);//参数isEmpty是false表示增量索引
             String storeId = "";
            boolean indexFlag = false;
             String id;
             String title;
            while (rs.next()) {
                // for(Iterator it = list.iterator();it.hasNext();){
                 id = rs.getString("id");
                 title = rs.getString("title");
                 writer.addDocument(Document(id, title));
                 storeId = id;//将拿到的id给storeId,这种拿法不合理,这里为了方便
                 indexFlag = true;
             }
             writer.optimize();
             writer.close();
            if(indexFlag){
                // 将最后一个的ID存到磁盘文件中
                this.writeStoreId(storeIdPath, storeId);
             }
            return true;
         } catch (Exception e) {
             e.printStackTrace();
             System.out.println("出错了" + e.getClass() + "\n    错误信息为:   "
                    + e.getMessage());
            return false;
         }

     }


    public static Document Document(String id, String title) {
         Document doc = new Document();
         doc.add(new Field("ID", id, Field.Store.YES, Field.Index.TOKENIZED));
         doc.add(new Field("TITLE", title, Field.Store.YES,
                 Field.Index.TOKENIZED));
        return doc;
     }

    // 取得存储在磁盘中的ID
    public static String getStoreId(String path) {
         String storeId = "";
        try {
             File file = new File(path);
            if (!file.exists()) {
                 file.createNewFile();
             }
             FileReader fr = new FileReader(path);
             BufferedReader br = new BufferedReader(fr);
             storeId = br.readLine();
            if (storeId == null || storeId == "")
                 storeId = "0";
             br.close();
             fr.close();
         } catch (Exception e) {
             e.printStackTrace();
         }
        return storeId;
     }

    // 将ID写入到磁盘文件中
    public static boolean writeStoreId(String path,String storeId) {
        boolean b = false;
        try {
             File file = new File(path);
            if (!file.exists()) {
                 file.createNewFile();
             }
             FileWriter fw = new FileWriter(path);
             PrintWriter out = new PrintWriter(fw);
             out.write(storeId);
             out.close();
             fw.close();
             b=true;
         } catch (IOException e) {
             e.printStackTrace();
         }
        return b;
     }
}

这里代码写的比较简单,很多需要改进的地方,自己改进就行了,这里只是说明了增量索引的原理,望指正。
转自:http://hi.baidu.com/lewutian/blog/item/e98c63d3f10f7ed3a9ec9ae2.html


这只是一种实现增量索引的方式,此方法可行,但是有人说这个很烂,我还会继续关注增量索引的。
分享到:
评论
1 楼 xiaoxiao_0311 2012-03-01  
增量不是这么个建法吧,应该加一个时间字段,每次增加,修改什么的,时间字段要更新,这样添加增量字段时以时间为基准就可以了,你的以id,做个小实验还可以,但如果真的是实用,人家的修改过的记录你不能更新到你的索引中,当然也可以用做个例

相关推荐

    基于lucene技术的增量索引

    本文将深入探讨如何利用Lucene实现增量索引,这是一种在数据库或文件系统更新时仅对新数据或变化数据进行索引的技术,以降低资源消耗并保持搜索性能。 **1. Lucene基础知识** Lucene首先需要理解的是它的核心概念,...

    Lucene5学习之增量索引(Zoie)

    《深入理解Lucene5增量索引与Zoie系统》 在信息检索领域,Lucene是一个广泛使用的全文搜索引擎库,其强大的索引能力和高效的搜索性能为开发者提供了强大的支持。然而,随着数据量的不断增长,如何高效地进行增量...

    lucene实现索引查询

    以下是关于使用Lucene实现索引查询的详细知识: ### 一、创建索引 创建索引是Lucene的核心过程,它涉及到以下步骤: 1. **定义索引目录**:首先,你需要指定一个目录来存储索引文件。这通常是一个文件夹,可以...

    lucene分词搜索,增量索引及全量索引

    本文将深入探讨Lucene的分词搜索、增量索引和全量索引的概念及其在实际应用中的实现方法。 一、Lucene分词搜索 Lucene的搜索功能基于分词技术。分词是将文本拆分成可搜索的独立单元,称为“词语”或“token”。...

    lucene索引结构原理.docx

    - **索引构建**:Lucene支持增量索引和批量索引,可以处理数据源的小幅变化或大规模数据。数据库通常需要全量重建索引,尤其是在数据发生变化时。 - **结果输出**:数据库查询返回RecordSet,而Lucene查询返回Hits...

    Solr数据库插入(全量和增量)索引

    本文将详细介绍 Solr 数据库插入全量和增量索引的方法和实现步骤。 全量索引 全量索引是指将整个数据集插入 Solr 索引库中,一般用于第一次创建索引的情况。在这种情况下,我们需要将所有数据从数据源中提取出来,...

    solr增量导入更新索引包

    Solr使用Lucene库作为其核心的索引引擎。索引是通过将文档转换为一系列可搜索的字段来创建的,这些字段包括文本、数字、日期等。索引存储在磁盘上,并且可以被优化以提高查询性能。 2. **增量更新的概念** 增量...

    增量索引2

    根据提供的文件信息,本文将重点解析“增量索引”这一概念及其在Lucene中的应用,并结合其他相关知识点进行深入探讨。 ### 增量索引概述 #### 1. 定义与背景 增量索引是指在现有索引的基础上,只对新增或更新的...

    Lucene.net建立索引,检索分页Demo

    - 增量索引:当新数据到来时,无需重新构建整个索引,而是使用 IndexWriter 的 UpdateDocument 或 AddDocument 方法更新已存在的索引。 - 倒排索引:Lucene 使用倒排索引来加速搜索,每个词项对应一组包含它的文档...

    基于Lucene的分布式并行索引.pdf

    除了倒排索引,Lucene还支持增量索引,这意味着可以只对文档的更改部分进行索引更新,而不是重新对整个文档集进行索引,从而节省资源并提高效率。 然而,尽管Lucene提供了强大的索引能力,但在实际应用中,随着索引...

    【大搜集:lucene学习资料】---<下载不扣分,回帖加1分,欢迎下载,童叟无欺>

    lucene为数据库搜索建立增量索引.txt lucene数据库索引.txt 新闻系统全文检索的思绪.txt lucene学习笔记 1 .txt lucene学习笔记 2.txt lucene学习笔记 3 .txt lucene入门实战.txt Lucene 的学习 .txt ...

    利用Lucene.NET建立SQL数据库记录索引文件程序C#源代码(包含数据库结构)

    对初学使用dotlucent作站内检索的比较有帮助。 利用dotlucene为网站做的索引文件的应用程序。 数据库源是SQL Server,项目是...应用程序界面可以配置数据库链接,生成报告,定时执行增量索引,对单条索引进行更新操作。

    跟益达学Solr5之增量索引MySQL数据库表数据

    本教程以"跟益达学Solr5之增量索引MySQL数据库表数据"为主题,旨在教授如何利用Solr5来实现对MySQL数据库表数据的增量索引,以便在海量数据中快速检索。 首先,我们需要了解Solr的基本架构。Solr运行在Jetty服务器...

    lucene索引

    4. **实时性需求**:如果应用需要实时更新索引,需要考虑增量索引和实时搜索的实现,确保新添加的数据能快速被搜索到。 5. **中文处理**:中文的分词难度较大,需要选择合适的分词器,并处理好词性的识别和词语的...

    Nutch开源搜索引擎增量索引recrawl的终极解决办法续

    针对上述问题,我们可以通过以下步骤来实现增量索引recrawl的终极解决方案: 1. **确认索引文件结构**: - 在执行`indexmerge`之前,确保所有需要合并的索引文件都已准备就绪,并且这些文件是正确的版本。 - 使用...

    lucene.net实例

    本文将深入探讨如何利用 Lucene.NET 实现全文检索,包括增量索引、更新索引和删除索引等关键操作。 **1. 全文检索基础** 全文检索是通过分析文本中的关键词来查找相关信息的技术。Lucene.NET 提供了一种高效的倒排...

    lucene搜索引擎项目

    Lucene支持增量索引,意味着可以对新的或已更改的数据进行实时更新。索引优化则是一次性合并多个段(segments)的过程,以提高搜索性能。 5. **搜索结果相关性** Lucene通过TF-IDF(Term Frequency-Inverse ...

    基于Lucene的超强配置式索引应用

    另外,可以利用Lucene的近实时搜索特性,通过NRTManager(Near Real Time Search Manager)实现快速的增量索引和查询。 除了上述基础配置,还可以扩展Lucene的功能,如使用Filter进行结果过滤,使用Highlighter高亮...

    Lucene与关系型数据库对比

    Lucene通过建立反向索引,并支持增量索引,极大地提高了索引效率。此外,用户还可以通过控制哪些字段需要索引,哪些字段无需索引,以及是否需要对索引字段进行分词处理,来优化索引策略。 ### 关系型数据库:事务...

    行业分类-设备装置-一种修改Lucene索引文件中词的方法及装置.zip

    例如,更新可能用于纠正错误的词汇,删除可能用于处理被删除的文档,而添加则可能用于增量索引。 5. 装置设计:这里提到的“装置”可能是指硬件或软件系统,用于实施上述方法,可能涉及到分布式索引更新策略,确保...

Global site tag (gtag.js) - Google Analytics