自己动手写分布式搜索引擎
上QQ阅读APP看书,第一时间看更新

3.2.5 更新索引库中的索引文档

对于分词列来说,直接更新索引中的值很困难。可以采用先删除旧文档,然后再向索引增加传入的新文档的方法实现更新索引。

通过IndexWriter.updateDocument方法更新文档。

        indexWriter.updateDocument(new Term("url", "http://www.lietu.com"), document);

如果只希望更新个别列而保持其他的列不动就会有问题。为了解决这个问题,可以搜索索引中的当前文档,改变要改变的列,然后把修改后的文档作为参数传给updateDocument()。

        public void searchAndUpdateDocument(IndexWriter writer,
                                        IndexSearcher searcher,
                                        Document updateDoc,
                                        Term term) throws IOException {
              TermQuery query = new TermQuery(term);


              TopDocs hits = searcher.search(query, 10);


              if (hits.scoreDocs.length == 0) {
                      throw new IllegalArgumentException("索引中没有匹配的结果");
              } else if (hits.scoreDocs.length > 1) {
                      throw new IllegalArgumentException("Given Term matches
                        more than 1 document in the index.");
              } else {
                      int docId = hits.scoreDocs[0].doc;


                      //找出旧的文档
                      Document doc = searcher.doc(docId);


                      List<Field> replacementFields = updateDoc.getFields();
                      for (Field field : replacementFields) {
                            String name = field.name();
                            String currentValue = doc.get(name);
                            if (currentValue ! = null) {
                                  //替换列值
                                  Field = new Field(name, term.text());
                                  //删除所有出现的值旧列
                                  doc.removeFields(name);


                                  //插入替换列
                                  doc.add(field);
                            } else {
                                  //新加到列
                                  doc.add(field);
                            }
                    }


                    //把旧文档更改后重新写入索引
                    writer.updateDocument(term, doc);
              }
      }