`
ttitfly
  • 浏览: 623883 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

通过updateDocument更新索引

阅读更多
package com.lucene;

import java.io.IOException;

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;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.Hits;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;

public class UpdateDocument {
	
	private static String path = "d:/index";
	
	
	public static void main(String[] args){
//		addIndex();
		updateIndex();
		search("李四");
		search("王五");
	}
	
	public static void addIndex(){
		try {
			IndexWriter write = new IndexWriter(path,new StandardAnalyzer(),true);
			
			Document doc = new Document();
			doc.add(new Field("id","123456",Field.Store.YES,Field.Index.UN_TOKENIZED));
			doc.add(new Field("userName","张三",Field.Store.YES,Field.Index.TOKENIZED));
			doc.add(new Field("comefrom","北京",Field.Store.YES,Field.Index.TOKENIZED));
			
			write.addDocument(doc);
			
			write.close();
			
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	
	public static void updateIndex(){
		try {
			
			IndexWriter write = new IndexWriter(path,new StandardAnalyzer(),false);
			Document docNew = new Document();
			docNew.add(new Field("id","123456",Field.Store.YES,Field.Index.UN_TOKENIZED));
			docNew.add(new Field("userName","王五",Field.Store.YES,Field.Index.TOKENIZED));
			Term term = new Term("id","123456");
			/**
			  调用updateDocument的方法,传给它一个新的doc来更新数据,
			  Term term = new Term("id","1234567");
			  先去索引文件里查找id为1234567的Doc,如果有就更新它(如果有多条,最后更新后只有一条)。如果没有就新增.
			 
			  数据库更新的时候,我们可以只针对某个列来更新,而lucene只能针对一行数据更新。
			 */
			write.updateDocument(term, docNew);
			
			write.close();
			
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static Query queryParser(String str){
		QueryParser queryParser = new QueryParser("userName", new StandardAnalyzer());
		try {
			Query query =  queryParser.parse(str);
			return query;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	
	public static void search(String str){
		try {
			IndexSearcher search = new IndexSearcher(path);
			
			Query query = queryParser(str);
			
			Hits hits = search.search(query);
			if(hits==null){
				return;
			}
			if(hits.length() == 0){
				System.out.println(" 没有搜索到'" + str+"'");
				return;
			}
			for (int i = 0; i < hits.length(); i++) {
				Document doc = hits.doc(i);
				System.out.println("id = "+hits.id(i));
				System.out.println("own id = " + doc.get("id"));
				System.out.println("userName = "+doc.get("userName"));
				System.out.println("come from  = "+doc.get("comefrom"));
				System.out.println("");
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}

分享到:
评论
3 楼 TonyLian 2010-02-02  
有没有发现:更新后,下次再打开索引。
indexReader.maxDoc()的数量翻番了。
而且索引目录所占用的磁盘空间也翻番了(旧的索引文件还在,新的索引文件大小和旧的一样大)

只有在write.close();
前写 writer.optimize();
才可以避免此问题。

但是,writer.optimize();是一个很耗时、耗资源的动作。单单空白磁盘空间的需求就只是要有2倍于翻了翻后的索引文件的大小。

如果经常要updateDocument的话,每次都writer.optimize();会大大影响性能,不知道有没有两全其美的好方法?
2 楼 hqman 2008-09-21  
package com.wangkai.lucene;

import java.io.IOException;

import junit.framework.TestCase;

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;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.Hits;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;

public class UpdateDocumentTests extends TestCase {

private static String path = "/home/hqman/shell/index";

public static void main(String[] args) {
// addIndex();
updateIndex();
search("李四");
search("王五");
}

public static void addIndex() {
try {
IndexWriter write = new IndexWriter(path, new StandardAnalyzer(),
true);

Document doc = new Document();
doc.add(new Field("id", "123456", Field.Store.YES,
Field.Index.UN_TOKENIZED));
doc.add(new Field("userName", "张三", Field.Store.YES,
Field.Index.TOKENIZED));
doc.add(new Field("comefrom", "北京", Field.Store.YES,
Field.Index.TOKENIZED));

write.addDocument(doc);

write.close();

} catch (IOException e) {
e.printStackTrace();
}
}

public static void updateIndex() {
try {

IndexWriter write = new IndexWriter(path, new StandardAnalyzer(),
false);
Document docNew = new Document();
docNew.add(new Field("id", "123456", Field.Store.YES,
Field.Index.UN_TOKENIZED));
docNew.add(new Field("userName", "王五", Field.Store.YES,
Field.Index.TOKENIZED));
Term term = new Term("id", "123456");
/**
* 调用updateDocument的方法,传给它一个新的doc来更新数据, Term term = new
* Term("id","1234567");
* 先去索引文件里查找id为1234567的Doc,如果有就更新它(如果有多条,最后更新后只有一条)。如果没有就新增.
*
* 数据库更新的时候,我们可以只针对某个列来更新,而lucene只能针对一行数据更新。
*/
//write.updateDocument(term, docNew);
//write.addDocument( docNew);

Document doc = new Document();
doc.add(new Field("id", "123456", Field.Store.YES,
Field.Index.UN_TOKENIZED));
doc.add(new Field("userName", "张三", Field.Store.YES,
Field.Index.TOKENIZED));
doc.add(new Field("comefrom", "北京", Field.Store.YES,
Field.Index.TOKENIZED));

write.addDocument(doc);

write.close();

} catch (IOException e) {
e.printStackTrace();
}
}

public static Query queryParser(String str) {
QueryParser queryParser = new QueryParser("userName",
new StandardAnalyzer());
try {
Query query = queryParser.parse(str);
return query;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}

public static void search(String str) {
try {
IndexSearcher search = new IndexSearcher(path);

Query query = queryParser(str);

Hits hits = search.search(query);
if (hits == null) {
return;
}
if (hits.length() == 0) {
System.out.println(" 没有搜索到'" + str + "'");
return;
}
System.out.println(" 搜索到:" + hits.length() + "'");

for (int i = 0; i < hits.length(); i++) {
Document doc = hits.doc(i);
System.out.println("id = " + hits.id(i));
System.out.println("own id = " + doc.get("id"));
System.out.println("userName = " + doc.get("userName"));
System.out.println("come from  = " + doc.get("comefrom"));
System.out.println("");
}

} catch (Exception e) {
e.printStackTrace();
}
}


public void testUpdate(){
addIndex();
updateIndex();
search("张三");

}
}


测试了 结果是 2条

搜索到:2'
id = 0
own id = 123456
userName = 张三
come from  = 北京

id = 1
own id = 123456
userName = 张三
come from  = 北京

1 楼 hqman 2008-09-21  
奇怪 我直接 writer.addDocument(doc); 也可以完成 更新索引

相关推荐

    solr增量导入更新索引包

    - **Update Handler**:Solr提供了多种Update Handler,例如Direct Update Handler和Document Update Handler,它们接收单个文档或者批量文档的更新请求,然后进行相应的索引更新,而无需重新构建整个索引。...

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

    IndexWriter提供了如addDocument()和updateDocument()的方法,用于处理单个文档的增删改操作。 三、全量索引 全量索引则是对所有数据重新构建索引的过程。在系统启动时、数据库初始化或数据发生重大变化时,全量...

    Lucene5写的全文搜索的demo,包括创建索引和搜索

    Lucene 提供了 `IndexWriter` 的 `updateDocument()` 方法来替换现有文档。 总结,Lucene5 全文搜索 demo 展示了如何利用 Lucene 的核心组件创建和搜索索引。从索引的构建到查询的执行,每个步骤都涉及到对 Lucene ...

    solr定时索引

    增量索引:增量索引是指只对自上次索引以来发生变化的数据进行索引更新。这种方式适用于数据频繁更新但整体变化不大的情况,可以有效减少索引过程的时间和资源消耗。在Solr中,通常会配合数据导入工具...

    lucene索引的简单使用

    1. **更新与删除**:Lucene提供了updateDocument和deleteDocuments方法来更新已存在的文档或删除指定的文档。 2. **性能优化**:可以通过设置批处理大小、使用多线程、利用缓存等方式优化索引和查询性能。 3. **...

    Solr全文索引

    - **更新和删除**:同样,SolrNet提供了Update和Delete方法来更新或删除索引中的文档。 4. **Solr的高级特性** - **Faceting**:允许用户对搜索结果进行分类,如按类别、品牌等维度统计。 - **Highlighting**:...

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

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

    56 solrCloud分布式搜索与索引过程

    - **Document**:索引中的最小单位,类似于关系数据库中的行。 - **Field**:文档中的属性或列。 #### 知识点三:Solr节点组成与客户端搜索请求 - **Solr节点组成**: - **Core**:每个Solr节点由一个或多个...

    lucene.net实例

    在 Lucene.NET 中,可以通过 IndexWriter 类的 AddDocument 和 UpdateDocument 方法来实现增量索引。 **3. 更新索引** 更新索引涉及到已存在文档的更改。Lucene.NET 不直接支持文档级别的更新,而是采用删除旧文档...

    Lucene4.X实战类baidu搜索的大型文档海量搜索系统-16.Lucene高级进阶2 共4页.pptx

    当需要更新已有索引中的某个文档时,我们不能直接修改,而是需要创建一个新的Document对象,并使用`writer.updateDocument()`方法。例如,以下代码片段展示了如何更新一个文档: ```java IndexWriterConfig iwc = ...

    ElasticSearch RestHighLevelClient 关于索引库、文档的基础操作

    4. **更新文档**:使用`update()`方法,通过UpdateRequest构建更新请求。可以是部分更新或脚本更新。例如: ```java UpdateRequest updateRequest = new UpdateRequest("my_index", "1"); Map, Object&gt; doc = new...

    Lucene实现索引和查询的实例讲解

    Lucene的索引建立可以通过IndexWriter类实现,IndexWriter类提供了多种方法来建立索引,包括addDocument方法、updateDocument方法、deleteDocument方法等。 Lucene的查询可以通过Searcher类实现,Searcher类提供...

    Lucene3.0 Demo

    - **更新文档**:通过`updateDocument()`方法,你可以替换索引中已有的文档。这通常基于一个唯一标识符(如ID)来定位文档。 - **删除文档**:`deleteDocuments(Term)`或`deleteDocuments(Query)`方法可删除指定的...

    Lucene4.X实战类baidu搜索的大型文档海量搜索系统-15.Lucene高级进阶1 共23页.pptx

    4. **更新索引中的Document**:介绍了如何在不重建整个索引的情况下更新已存在的Document,利用`IndexWriter`的`updateDocument()`方法。 5. **分页搜索**:由于Lucene的查询特性,需要实现分页查询策略,通常先...

    lucene3小例子

    如果需要更新文档,可以调用`updateDocument(Term term, Document newDoc)`方法。完成所有文档的索引后,记得调用`close()`关闭`IndexWriter`。 查询阶段,我们需要创建`IndexSearcher`对象,它从Directory读取索引...

    lucene3.0-api.CHM

    2. 更新索引:当文档有变化时,可以使用IndexWriter的updateDocument方法进行更新。 3. 搜索索引:使用IndexSearcher实例和Query对象执行搜索,然后使用HitCollector获取结果。 4. 高亮显示:使用Highlighter类...

    lucene的curd

    四、更新索引(Update) 更新索引涉及到删除已有的文档并重新添加。在Lucene中,更新通常意味着先删除再创建新的索引。使用`IndexWriter`的`deleteDocuments()`方法可以删除特定文档。 ```java indexWriter....

    基于lucene搜索引擎的java源码

    源码中可能使用了`IndexWriter.addDocument()`或`IndexWriter.updateDocument()`方法,前者用于添加新文档,后者用于更新已存在的文档。 3. **搜索(Searching)**:`IndexSearcher`和`QueryParser`类是进行搜索的...

    Lucene4.X实战类baidu搜索的大型文档海量搜索系统-17.Lucene高级进阶3 共4页.pptx

    当需要更新已有文档时,可以使用`IndexWriter`的`updateDocument()`方法,结合`OpenMode`设置为`CREATE_OR_APPEND`,以确保既能够创建新索引,也能追加到已有索引。 2. **分页搜索的实现**: 由于Lucene查询结果的...

    lucene 2.1.0 好用实例

    通过`IndexWriter.addDocument()`或`updateDocument()`方法,我们可以轻松实现对索引的动态维护。 ### 二、Lucene 查询 1. **查询构造**:Lucene提供丰富的查询语法,如布尔查询、短语查询、范围查询等。我们可以...

Global site tag (gtag.js) - Google Analytics