Lucene教程(四) 索引的更新和删除
这篇文章是基于上一篇文章来写的,使用的是IndexUtil类,下面的例子不在贴出整个类的内容,只贴出具体的方法内容。
3.5版本:
先写了一个check()方法来查看索引文件的变化:
- /**
- * 检查一下索引文件
- */
- public static void check() {
- IndexReader indexReader = null;
- try {
- Directory directory = FSDirectory.open(new File("F:/test/lucene/index"));
- indexReader = IndexReader.open(directory);
- // 通过reader可以有效的获取到文档的数量
- // 有效的索引文档
- System.out.println("有效的索引文档:" + indexReader.numDocs());
- // 总共的索引文档
- System.out.println("总共的索引文档:" + indexReader.maxDoc());
- // 删掉的索引文档,其实不恰当,应该是在回收站里的索引文档
- System.out.println("删掉的索引文档:" + indexReader.numDeletedDocs());
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- try {
- if (indexReader != null) {
- indexReader.close();
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
那么就下来就先跑一下建立索引方法,然后在执行以下check()方法,看看结果:
- 有效的索引文档:3
- 总共的索引文档:3
- 删掉的索引文档:0
接下来我想删除一个索引,例子如下:
- /**
- * 删除索引
- */
- public static void delete() {
- IndexWriter indexWriter = null;
- try {
- Directory directory = FSDirectory.open(new File("F:/test/lucene/index"));
- Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_35);
- IndexWriterConfig indexWriterConfig = new IndexWriterConfig(Version.LUCENE_35, analyzer);
- indexWriter = new IndexWriter(directory, indexWriterConfig);
- /**
- * 参数是一个选项,可以是一个Query,也可以是一个term,term是一个精确查找的值
- *
- * 此时删除的文档并不会被完全删除,而是存储在一个回收站中的,可以恢复
- */
- // 方式一:通过Term删除
- /**
- * 注意Term构造器的意思,第一个参数为Field,第二个参数为Field的值
- */
- indexWriter.deleteDocuments(new Term("id", "1"));
- // 方式二:通过Query删除
- /**
- * 这里就要造一个Query出来,删掉查处的索引
- */
- QueryParser queryParser = new QueryParser(Version.LUCENE_35, "content", analyzer);
- // 创建Query表示搜索域为content包含Lucene的文档
- Query query = queryParser.parse("Lucene");
- // indexWriter.deleteDocuments(query);
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- try {
- if (indexWriter != null) {
- indexWriter.close();
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
看看测试:
- @Test
- public void testDelete() {
- IndexUtil.delete();
- IndexUtil.check();
- }
执行过后:
- 有效的索引文档:2
- 总共的索引文档:3
- 删掉的索引文档:1
此时被删掉的文档跑到了回收站中,并没有被彻底删除,我们上面使用的是删term的方式,那么使用query删行不行呢,那么现在把注释换一换:
- // indexWriter.deleteDocuments(new Term("id", "1"));
- // 方式二:通过Query删除
- /**
- * 这里就要造一个Query出来,删掉查处的索引
- */
- QueryParser queryParser = new QueryParser(Version.LUCENE_35, "content", analyzer);
- // 创建Query表示搜索域为content包含Lucene的文档
- Query query = queryParser.parse("Lucene");
- indexWriter.deleteDocuments(query);
再跑一下测试方法:
- 有效的索引文档:1
- 总共的索引文档:3
- 删掉的索引文档:2
看看,被删除的文档又多了一个,因为我们query查出的文档和id为1的文档不是同一个,目前了解了删除的两种方式怎么使用了吧。
我现在发现删错了,想恢复怎么办,那么我们就来看看怎么恢复删除的索引:
- /**
- * 恢复删除的索引
- */
- public static void unDelete() {
- // 使用IndexReader进行恢复
- IndexReader indexReader = null;
- try {
- Directory directory = FSDirectory.open(new File("F:/test/lucene/index"));
- // 恢复时,必须把IndexReader的只读(readOnly)设置为false
- // 索引没有改变可以使用true,但现在是恢复删除的索引,显然是改变过的,所以只能是false
- indexReader = IndexReader.open(directory, false);
- indexReader.undeleteAll();
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- try {
- if (indexReader != null) {
- indexReader.close();
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
跑一下测试:
- @Test
- public void testUnDelete() {
- IndexUtil.unDelete();
- IndexUtil.check();
- }
结果为:
- 有效的索引文档:3
- 总共的索引文档:3
- 删掉的索引文档:0
全部恢复了吧,很不错吧
但是我现在有发现刚才没有删错,我要把索引彻底删除,怎么弄呢,我们回过头来再试,我现在吧删除索引的两种方式的注释都打开,执行一下删除方法是不是得到这样的结果啊:
- 有效的索引文档:1
- 总共的索引文档:3
- 删掉的索引文档:2
然后看看彻底删除的代码:
- /**
- * 强制删除
- */
- public static void forceDelete() {
- IndexWriter indexWriter = null;
- try {
- Directory directory = FSDirectory.open(new File("F:/test/lucene/index"));
- Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_35);
- IndexWriterConfig indexWriterConfig = new IndexWriterConfig(Version.LUCENE_35, analyzer);
- indexWriter = new IndexWriter(directory, indexWriterConfig);
- indexWriter.forceMergeDeletes();
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- try {
- if (indexWriter != null) {
- indexWriter.close();
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
执行一下测试代码:
- @Test
- public void testForceDelete() {
- IndexUtil.forceDelete();
- IndexUtil.check();
- }
结果如下:
- 有效的索引文档:1
- 总共的索引文档:1
- 删掉的索引文档:0
此时两个索引文档被彻底的删掉了。这么长都在讲删除的事,那么Lucene是怎么更新索引的呢,记下来看看是如何更新索引的:
注:先把索引文件删除,重新建索引
- /**
- * 更新索引
- */
- public static void update() {
- IndexWriter indexWriter = null;
- try {
- Directory directory = FSDirectory.open(new File("F:/test/lucene/index"));
- Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_35);
- IndexWriterConfig indexWriterConfig = new IndexWriterConfig(Version.LUCENE_35, analyzer);
- indexWriter = new IndexWriter(directory, indexWriterConfig);
- /**
- * Lucene并没有提供更新,这里的更新操作其实是如下两个操作的合集 先删除之后再添加
- */
- Document document = new Document();
- document.add(new Field("id", "11", Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS));
- document.add(new Field("author", authors[0], Field.Store.YES, Field.Index.NOT_ANALYZED));
- document.add(new Field("title", titles[0], Field.Store.YES, Field.Index.ANALYZED));
- document.add(new Field("content", contents[1], Field.Store.NO, Field.Index.ANALYZED));
- indexWriter.updateDocument(new Term("id", "1"), document);
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- try {
- if (indexWriter != null) {
- indexWriter.close();
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
注意上边这段代码,我使用的content是id为2的content,它包含“Lucene”,我一会要用它测试,注意比对结果
此时执行一下更新索引:
- @Test
- public void testUpdate() {
- IndexUtil.update();
- IndexUtil.check();
- }
结果为:
- 有效的索引文档:3
- 总共的索引文档:4
- 删掉的索引文档:1
结果是这样的,惊讶吗,我们一起来算算,有效的文档删掉一个添加一个是不是3个,没错吧,总共的文档数是三个加一个,引文删掉的文档也算啊,没有彻底删掉,在回收站里,然后我们执行一下search()方法,看看结果:
- /**
- * 搜索
- */
- public static void search() {
- IndexReader indexReader = null;
- try {
- // 1、创建Directory
- Directory directory = FSDirectory.open(new File("F:/test/lucene/index"));
- // 2、创建IndexReader
- indexReader = IndexReader.open(directory);
- // 3、根据IndexReader创建IndexSearch
- IndexSearcher indexSearcher = new IndexSearcher(indexReader);
- // 4、创建搜索的Query
- // 使用默认的标准分词器
- Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_35);
- // 在content中搜索Lucene
- // 创建parser来确定要搜索文件的内容,第二个参数为搜索的域
- QueryParser queryParser = new QueryParser(Version.LUCENE_35, "content", analyzer);
- // 创建Query表示搜索域为content包含Lucene的文档
- Query query = queryParser.parse("Lucene");
- // 5、根据searcher搜索并且返回TopDocs
- TopDocs topDocs = indexSearcher.search(query, 10);
- // 6、根据TopDocs获取ScoreDoc对象
- ScoreDoc[] scoreDocs = topDocs.scoreDocs;
- for (ScoreDoc scoreDoc : scoreDocs) {
- // 7、根据searcher和ScoreDoc对象获取具体的Document对象
- Document document = indexSearcher.doc(scoreDoc.doc);
- // 8、根据Document对象获取需要的值
- System.out.println("id : " + document.get("id"));
- System.out.println("author : " + document.get("author"));
- System.out.println("title : " + document.get("title"));
- /**
- * 看看content能不能打印出来,为什么?
- */
- System.out.println("content : " + document.get("content"));
- }
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- try {
- if (indexReader != null) {
- indexReader.close();
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
- @Test
- public void testSearch() {
- IndexUtil.search();
- }
- id : 2
- author : Tony
- title : Hello Lucene
- content : null
- id : 11
- author : Darren
- title : Hello World
- content : null
查出来了两条,说明更新成功了
我再把id为3的索引也更新一下:
- Document document = new Document();
- document.add(new Field("id", "11", Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS));
- document.add(new Field("author", authors[0], Field.Store.YES, Field.Index.NOT_ANALYZED));
- document.add(new Field("title", titles[0], Field.Store.YES, Field.Index.ANALYZED));
- document.add(new Field("content", contents[1], Field.Store.NO, Field.Index.ANALYZED));
- indexWriter.updateDocument(new Term("id", "3"), document);
执行一下update()方法,看看结果:
- 有效的索引文档:3
- 总共的索引文档:5
- 删掉的索引文档:2
问题来了,随着索引文件更新次数的增加,索引文件是不是会越来越多啊,那我们是不是有办法合并一下优化一下呢,下面来看Lucene是怎么合并索引文件的:
- /**
- * 合并索引
- */
- public static void merge() {
- IndexWriter indexWriter = null;
- try {
- Directory directory = FSDirectory.open(new File("F:/test/lucene/index"));
- Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_35);
- IndexWriterConfig indexWriterConfig = new IndexWriterConfig(Version.LUCENE_35, analyzer);
- indexWriter = new IndexWriter(directory, indexWriterConfig);
- // 会将索引合并为2段,这两段中的被删除的数据会被清空
- /**
- * 特别注意:
- *
- * 此处Lucene在3.5之后不建议使用,因为会消耗大量的开销,Lucene会根据情况自动处理的
- */
- // 把索引合并为两段
- indexWriter.forceMerge(2);
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- try {
- if (indexWriter != null) {
- indexWriter.close();
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
执行一下测试:
- @Test
- public void testMerge() {
- IndexUtil.merge();
- IndexUtil.check();
- }
结果为:
- 有效的索引文档:3
- 总共的索引文档:3
- 删掉的索引文档:0
索引文件数恢复正常了,这里有个问题,Lucene的合并索引方法或优化索引方法不建议人为调用,会消耗很多资源,并且Lucene会自动优化索引,索引不用担心索引文件一直变大变多这个问题。
4.5版本:
首先看看check()方法,和3.5版本一样:
- /**
- * 检查一下索引文件
- */
- public static void check() {
- DirectoryReader directoryReader = null;
- try {
- Directory directory = FSDirectory.open(new File("F:/test/lucene/index"));
- directoryReader = DirectoryReader.open(directory);
- // 通过reader可以有效的获取到文档的数量
- // 有效的索引文档
- System.out.println("有效的索引文档:" + directoryReader.numDocs());
- // 总共的索引文档
- System.out.println("总共的索引文档:" + directoryReader.maxDoc());
- // 删掉的索引文档,其实不恰当,应该是在回收站里的索引文档
- System.out.println("删掉的索引文档:" + directoryReader.numDeletedDocs());
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- try {
- if (directoryReader != null) {
- directoryReader.close();
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
接下来看看删除方法:
- /**
- * 删除索引
- */
- public static void delete() {
- IndexWriter indexWriter = null;
- try {
- Directory directory = FSDirectory.open(new File("F:/test/lucene/index"));
- Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_45);
- IndexWriterConfig indexWriterConfig = new IndexWriterConfig(Version.LUCENE_45, analyzer);
- indexWriter = new IndexWriter(directory, indexWriterConfig);
- /**
- * 参数是一个选项,可以是一个Query,也可以是一个term,term是一个精确查找的值
- *
- * 此时删除的文档并不会被完全删除,而是存储在一个回收站中的,可以恢复
- */
- // 方式一:通过Term删除
- /**
- * 注意Term构造器的意思,第一个参数为Field,第二个参数为Field的值
- */
- indexWriter.deleteDocuments(new Term("id", "1"));
- // 方式二:通过Query删除
- /**
- * 这里就要造一个Query出来,删掉查处的索引
- */
- QueryParser queryParser = new QueryParser(Version.LUCENE_45, "content", analyzer);
- // 创建Query表示搜索域为content包含Lucene的文档
- Query query = queryParser.parse("Lucene");
- // indexWriter.deleteDocuments(query);
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- try {
- if (indexWriter != null) {
- indexWriter.close();
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
然后我们跑一下测试看看结果:记住要跑一下索引方法
- @Test
- public void testDelete() {
- IndexUtil.delete();
- IndexUtil.check();
- }
- 有效的索引文档:3
- 总共的索引文档:3
- 删掉的索引文档:0
没有删掉,为什么,经网络搜索,发现有人遇到了这个问题,解释是这样的,我现在是按term删,但是删除的term的text类型和建索引时的不一样,他其实是找不到这个term对应的内容,修改一下建立索引的方法:
把这段逻辑
- FieldType idType = new FieldType();
- idType.setStored(true);
- idType.setIndexed(false);
- idType.setOmitNorms(false);
- document.add(new Field("id", ids[i], idType));
改为:
document.add(new Field("id", ids[i], StringField.TYPE_STORED));
这样Id就是使用StringField去建立的索引,和我们term里的第二个参数类型一样了,再来试试
- 有效的索引文档:2
- 总共的索引文档:3
- 删掉的索引文档:1
现在可以了,但是这里就有问题了,我们使用的预定义的类型,这种类型是不可改的,我就不能对id使用自定义类型了,这不就不如3.5灵活了吗,不知道有没有人有什么高见。
接下来看看恢复方法:
- /**
- * 恢复删除的索引
- */
- public static void unDelete() {
- IndexWriter indexWriter = null;
- try {
- Directory directory = FSDirectory.open(new File("F:/test/lucene/index"));
- Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_45);
- IndexWriterConfig indexWriterConfig = new IndexWriterConfig(Version.LUCENE_45, analyzer);
- indexWriter = new IndexWriter(directory, indexWriterConfig);
- /**
- * 注意:和3.5版本不同,不再使用IndexReader恢复删除的索引,而是使用IndexWriter的rollback()方法
- */
- indexWriter.rollback();
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- try {
- if (indexWriter != null) {
- indexWriter.close();
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
这里遇到了另外的问题,无法恢复,暂时还不知道原因
接下来看看强制删除:
- /**
- * 强制删除
- */
- public static void forceDelete() {
- IndexWriter indexWriter = null;
- try {
- Directory directory = FSDirectory.open(new File("F:/test/lucene/index"));
- Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_45);
- IndexWriterConfig indexWriterConfig = new IndexWriterConfig(Version.LUCENE_45, analyzer);
- indexWriter = new IndexWriter(directory, indexWriterConfig);
- indexWriter.forceMergeDeletes();
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- try {
- if (indexWriter != null) {
- indexWriter.close();
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
- @Test
- public void testForceDelete() {
- IndexUtil.forceDelete();
- IndexUtil.check();
- }
- 有效的索引文档:2
- 总共的索引文档:2
- 删掉的索引文档:0
结果是正确的
我们来看看更新方法:
- /**
- * 更新索引
- */
- public static void update() {
- IndexWriter indexWriter = null;
- try {
- Directory directory = FSDirectory.open(new File("F:/test/lucene/index"));
- Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_45);
- IndexWriterConfig indexWriterConfig = new IndexWriterConfig(Version.LUCENE_45, analyzer);
- indexWriter = new IndexWriter(directory, indexWriterConfig);
- /**
- * Lucene并没有提供更新,这里的更新操作其实是如下两个操作的合集 先删除之后再添加
- */
- Document document = new Document();
- document.add(new Field("id", "11", StringField.TYPE_STORED));
- document.add(new Field("author", authors[0], StringField.TYPE_STORED));
- document.add(new Field("title", titles[0], StringField.TYPE_STORED));
- document.add(new Field("content", contents[1], TextField.TYPE_NOT_STORED));
- indexWriter.updateDocument(new Term("id", "1"), document);
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- try {
- if (indexWriter != null) {
- indexWriter.close();
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
注意:这里有个问题和删除是一样的,就是对id建索引是所使用的类型和删除时的保持一致,否则就会查不到,就变成了添加索引而不删除索引
这里还是重新建索引再测试
- @Test
- public void testUpdate() {
- IndexUtil.update();
- IndexUtil.check();
- }
- 有效的索引文档:3
- 总共的索引文档:4
- 删掉的索引文档:1
更新了一条,那么我们把id为3的也更新:
- Document document = new Document();
- document.add(new Field("id", "33", StringField.TYPE_STORED));
- document.add(new Field("author", authors[0], StringField.TYPE_STORED));
- document.add(new Field("title", titles[0], StringField.TYPE_STORED));
- document.add(new Field("content", contents[1], TextField.TYPE_NOT_STORED));
- indexWriter.updateDocument(new Term("id", "3"), document);
再测:
- 有效的索引文档:3
- 总共的索引文档:5
- 删掉的索引文档:2
结果都是正确的,那么我们合并一下:
- /**
- * 合并索引
- */
- public static void merge() {
- IndexWriter indexWriter = null;
- try {
- Directory directory = FSDirectory.open(new File("F:/test/lucene/index"));
- Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_45);
- IndexWriterConfig indexWriterConfig = new IndexWriterConfig(Version.LUCENE_45, analyzer);
- indexWriter = new IndexWriter(directory, indexWriterConfig);
- // 会将索引合并为2段,这两段中的被删除的数据会被清空
- /**
- * 特别注意:
- *
- * 此处Lucene在3.5之后不建议使用,因为会消耗大量的开销,Lucene会根据情况自动处理的
- */
- // 把索引合并为两段
- indexWriter.forceMerge(2);
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- try {
- if (indexWriter != null) {
- indexWriter.close();
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
- @Test
- public void testMerge() {
- IndexUtil.merge();
- IndexUtil.check();
- }
- 有效的索引文档:3
- 总共的索引文档:3
- 删掉的索引文档:0
结果和3.5版本的一致
5.0版本:
先看删除方法:
- /**
- * 删除索引
- */
- public static void delete() {
- IndexWriter indexWriter = null;
- try {
- Directory directory = FSDirectory.open(FileSystems.getDefault().getPath("F:/test/lucene/index"));
- Analyzer analyzer = new StandardAnalyzer();
- IndexWriterConfig indexWriterConfig = new IndexWriterConfig(analyzer);
- indexWriter = new IndexWriter(directory, indexWriterConfig);
- /**
- * 参数是一个选项,可以是一个Query,也可以是一个term,term是一个精确查找的值
- *
- * 此时删除的文档并不会被完全删除,而是存储在一个回收站中的,可以恢复
- */
- // 方式一:通过Term删除
- /**
- * 注意Term构造器的意思,第一个参数为Field,第二个参数为Field的值
- */
- indexWriter.deleteDocuments(new Term("id", "1"));
- // 方式二:通过Query删除
- /**
- * 这里就要造一个Query出来,删掉查处的索引
- */
- QueryParser queryParser = new QueryParser("content", analyzer);
- // 创建Query表示搜索域为content包含Lucene的文档
- Query query = queryParser.parse("Lucene");
- // indexWriter.deleteDocuments(query);
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- try {
- if (indexWriter != null) {
- indexWriter.close();
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
跑一下测试:
- @Test
- public void testDelete() {
- IndexUtil.delete();
- IndexUtil.check();
- }
- 有效的索引文档:2
- 总共的索引文档:3
- 删掉的索引文档:1
她解决了4.5版本中的一个问题,非要建立索引的id的类型和term参数类型一致的问题。
恢复逻辑如下:
- /**
- * 恢复删除的索引
- */
- public static void unDelete() {
- IndexWriter indexWriter = null;
- try {
- Directory directory = FSDirectory.open(FileSystems.getDefault().getPath("F:/test/lucene/index"));
- Analyzer analyzer = new StandardAnalyzer();
- IndexWriterConfig indexWriterConfig = new IndexWriterConfig(analyzer);
- indexWriter = new IndexWriter(directory, indexWriterConfig);
- /**
- * 注意:和3.5版本不同,不再使用IndexReader恢复删除的索引,而是使用IndexWriter的rollback()方法
- */
- indexWriter.rollback();
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- try {
- if (indexWriter != null) {
- indexWriter.close();
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
目前和4.5版本有一样的问题,恢复不了,等待继续研究去解决这个问题。
其他代码如下:
- /**
- * 更新索引
- */
- public static void update() {
- IndexWriter indexWriter = null;
- try {
- Directory directory = FSDirectory.open(FileSystems.getDefault().getPath("F:/test/lucene/index"));
- Analyzer analyzer = new StandardAnalyzer();
- IndexWriterConfig indexWriterConfig = new IndexWriterConfig(analyzer);
- indexWriter = new IndexWriter(directory, indexWriterConfig);
- /**
- * Lucene并没有提供更新,这里的更新操作其实是如下两个操作的合集 先删除之后再添加
- */
- Document document = new Document();
- document.add(new Field("id", "33", StringField.TYPE_STORED));
- document.add(new Field("author", authors[0], StringField.TYPE_STORED));
- document.add(new Field("title", titles[0], StringField.TYPE_STORED));
- document.add(new Field("content", contents[1], TextField.TYPE_NOT_STORED));
- indexWriter.updateDocument(new Term("id", "1"), document);
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- try {
- if (indexWriter != null) {
- indexWriter.close();
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
- /**
- * 检查一下索引文件
- */
- public static void check() {
- DirectoryReader directoryReader = null;
- try {
- Directory directory = FSDirectory.open(FileSystems.getDefault().getPath("F:/test/lucene/index"));
- directoryReader = DirectoryReader.open(directory);
- // 通过reader可以有效的获取到文档的数量
- // 有效的索引文档
- System.out.println("有效的索引文档:" + directoryReader.numDocs());
- // 总共的索引文档
- System.out.println("总共的索引文档:" + directoryReader.maxDoc());
- // 删掉的索引文档,其实不恰当,应该是在回收站里的索引文档
- System.out.println("删掉的索引文档:" + directoryReader.numDeletedDocs());
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- try {
- if (directoryReader != null) {
- directoryReader.close();
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
- /**
- * 合并索引
- */
- public static void merge() {
- IndexWriter indexWriter = null;
- try {
- Directory directory = FSDirectory.open(FileSystems.getDefault().getPath("F:/test/lucene/index"));
- Analyzer analyzer = new StandardAnalyzer();
- IndexWriterConfig indexWriterConfig = new IndexWriterConfig(analyzer);
- indexWriter = new IndexWriter(directory, indexWriterConfig);
- // 会将索引合并为2段,这两段中的被删除的数据会被清空
- /**
- * 特别注意:
- *
- * 此处Lucene在3.5之后不建议使用,因为会消耗大量的开销,Lucene会根据情况自动处理的
- */
- // 把索引合并为两段
- indexWriter.forceMerge(2);
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- try {
- if (indexWriter != null) {
- indexWriter.close();
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
- /**
- * 强制删除
- */
- public static void forceDelete() {
- IndexWriter indexWriter = null;
- try {
- Directory directory = FSDirectory.open(FileSystems.getDefault().getPath("F:/test/lucene/index"));
- Analyzer analyzer = new StandardAnalyzer();
- IndexWriterConfig indexWriterConfig = new IndexWriterConfig(analyzer);
- indexWriter = new IndexWriter(directory, indexWriterConfig);
- indexWriter.forceMergeDeletes();
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- try {
- if (indexWriter != null) {
- indexWriter.close();
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
这些代码和4.5版本差别不大,运行结果和4.5版本也是一样的,就不再一一讲解
Lucene教程(四) 索引的更新和删除的更多相关文章
- ELK学习总结(2-4)bulk 批量操作-实现多个文档的创建、索引、更新和删除
bulk 批量操作-实现多个文档的创建.索引.更新和删除 ----------------------------------------------------------------------- ...
- pymongo创建索引、更新、删除
pymongo创建索引.更新.删除 索引创建 ## collection 为数据集合collection.create_Index({'需创建索引字段': 1})collection.ensu ...
- Mybatis入门教程之新增、更新、删除功能_java - JAVA
文章来源:嗨学网 敏而好学论坛www.piaodoo.com 欢迎大家相互学习 上一节说了Mybatis的框架搭建和简单查询,这次我们来说一说用Mybatis进行基本的增删改操作: 一. 插入一条数据 ...
- lucene索引的更新和删除
索引的删除: IndexReader和IndexWriter都由删除索引的功能,但这两者是有区别的, 使用IndexReader删除索引时,索引会马上被删除,其有两种方法,可以删除索引deleteDo ...
- Elasticsearch 索引、更新、删除文档
一.Elasticsearch 索引(新建)一个文档的命令: curl XPUT ' http://localhost:9200/test_es_order_index/test_es_order_t ...
- SQL.Cookbook 读书笔记4 插入更新和删除
第四章 插入更新和删除 4.1 插入数据 ,'PROGRA','NEW YOURK'); 4.2 从一个表向另一个表中复制 insert into dept_east(deptno,dname,loc ...
- CRL快速开发框架系列教程四(删除数据)
本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...
- SQL Server索引进阶:第十三级,插入,更新,删除
在第十级到十二级中,我们看了索引的内部结构,以及改变结构造成的影响.在本文中,继续查看Insert,update,delete和merge造成的影响.首先,我们单独看一下这四个命令. 插入INSERT ...
- Lucene 更新、删除、分页操作以及IndexWriter优化
更新操作如下: 注意:通过lukeall-1.0.0.jar 查看软件,我们可以看到,更新其实是先删除在插入, 前面我们知道索引库中有两部分的内容组成,一个是索引文件,另一个是目录文件, 目前我们更新 ...
随机推荐
- 事务的ACID和四个隔离级别
在实际的业务场景中,并发读写引出了和事务控制的需求.优秀的事务处理能力是关系型数据库(特别是oracle等商用RDBMS)相对于正当风口的NoSQL数据库的一大亮点.但这也从另一方面说明了事务控制的复 ...
- ylbtech-Tool:
ylbtech-Tool: 1.返回顶部 2.返回顶部 3.返回顶部 4.返回顶部 5.返回顶部 6.返回顶部 7.返回顶部 8.返回顶部 9.返回顶部 10. ...
- git grade 版本下载及安装
Git 2.11.1x64下载 gradle各版本下载地址 1. Git安装与配置 Gradle 用法总结
- alibaba fastjson的使用总结和心得
最初接触alibaba fastjson是由于其性能上的优势,对比原来采用codehause.jackson的解析,在hadoop平台上的手动转换对象有着将近1/3的性能提升,但随着开发应用越来越 ...
- mysql中的blob和text区别
经过查询资料发现 除了blob 还有tinyblob longblob mediumblob 当然text还有tinytext mediumtext longtext 都是最为大的存储 本质区别主要是 ...
- 778. Swim in Rising Water
▶ 给定方阵 grid,其元素的值为 D0n-1,代表网格中该点处的高度.现在网格中开始积水,时刻 t 的时候所有值不大于 t 的格点被水淹没,当两个相邻格点(上下左右四个方向)的值都不超过 t 的时 ...
- pom指定java编译版本和编码
方法一 <properties> <!-- 文件拷贝时的编码 --> <project.build.sourceEncoding>UTF-8</project ...
- Apache Shiro学习-2-Apache Shiro Web Support
Apache Shiro Web Support 1. 配置 将 Shiro 整合到 Web 应用中的最简单方式是在 web.xml 的 Servlet ContextListener 和 Fil ...
- 多线程中,ResultSet为空,报错空指针
最近在数据库查询数据时,由于数据量太大,使用了多线程,通过线程池建了好几个线程,然后调用了一个封装好的jdbc查询语句. 结果在多线程中,ResultSet报错空指针. 仔细查阅后,才发现多个线程访问 ...
- 95. Unique Binary Search Trees II (Tree; DFS)
Given n, generate all structurally unique BST's (binary search trees) that store values 1...n. For e ...