如何在apache Lucene

时间:2016-09-02 12:52:00

标签: java lucene full-text-search

目前,我可以将文档列表以及单个文档添加到apache lucene索引中。但是我在从索引更新文档时遇到了问题:

我的方法是上传文件后,所以在写入磁盘之前,我正在检查驱动器/文件夹中是否存在文件,并根据文件名删除索引。

其次,我将上传的文件添加到Lucene索引中。

但我遇到的问题是新添加的以及旧文档在搜索结果中显示的内容不同。

对于Ex:文件名为Sample_One.txt,文本为:

  

这是第一次的示例文本。

从索引中删除上述文件,然后将新文件内容添加到索引中。

现在使用具有相同文件名的另一个文本更新文件内容:

  

这是包含更新内容的示例文本。

在搜索某些文字时,例如“sample”,结果显示Sample_One.txt文件两次,包含旧内容和新内容。

我想知道我是否遗漏了某些内容以及如何将文档更新/删除到索引中。

代码片段是:

//Deleting the Document from the Index
public void deleteDocumentsFromIndexUsingTerm(Document doc) throws IOException, ParseException {
    Term fileTerm = new Term("file_name",doc.get("file_name"));
    Term contentTerm = new Term("content", doc.get("content"));
    Term docIDTerm = new Term("document_id", doc.get("document_id"));

    File indexDir = new File(INDEX_DIRECTORY);

    Directory directory = FSDirectory.open(indexDir.toPath());

    Analyzer analyzer = new StandardAnalyzer();
    IndexWriterConfig conf = new IndexWriterConfig(analyzer);
    IndexWriter indexWriter = new IndexWriter(directory, conf);

    System.out.println("Deleting the term with - "+doc.get("file_name"));
    System.out.println("Deleting the term with contents - "+doc.get("content"));

    indexWriter.deleteDocuments(fileTerm);
    indexWriter.deleteDocuments(contentTerm);
    indexWriter.deleteDocuments(docIDTerm);
    indexWriter.commit();
    indexWriter.close();
}

//将文档添加到索引

的代码段
final String INDEX_DIRECTORY = "D:\\Development\\Lucene_Indexer";
    long startTime = System.currentTimeMillis();
    List<ContentHandler> contentHandlerList = new ArrayList<ContentHandler>();

    String fileNames = (String)request.getAttribute("message");

    File file = new File("D:\\Development\\Resume_Sample\\"+fileNames);

    ArrayList<File> fileList = new ArrayList<File>();
    fileList.add(file);

    Metadata metadata = new Metadata();

    // BodyContentHandler set the value as -1 to evade the Text Limit Exception
    ContentHandler handler = new BodyContentHandler(-1);
    ParseContext context = new ParseContext();
    Parser parser = new AutoDetectParser();
    InputStream stream = new FileInputStream(file);

    try {
        parser.parse(stream, handler, metadata, context);
        contentHandlerList.add(handler);
    }catch (TikaException e) {
        e.printStackTrace();
    }catch (SAXException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    finally {
        try {
            stream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    FieldType fieldType = new FieldType();
    fieldType.setIndexOptions(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS);
    fieldType.setStoreTermVectors(true);
    fieldType.setStoreTermVectorPositions(true);
    fieldType.setStoreTermVectorPayloads(true);
    fieldType.setStoreTermVectorOffsets(true);
    fieldType.setStored(true);


    Analyzer analyzer = new StandardAnalyzer();
    Directory directory = FSDirectory.open(new File(INDEX_DIRECTORY).toPath());
    IndexWriterConfig conf = new IndexWriterConfig(analyzer);
    IndexWriter writer = new IndexWriter(directory, conf);

    Iterator<ContentHandler> handlerIterator = contentHandlerList.iterator();
    Iterator<File> fileIterator = fileList.iterator();

while (handlerIterator.hasNext() && fileIterator.hasNext()) {
    Document doc = new Document();

    String text = handlerIterator.next().toString();
    String textFileName = fileIterator.next().getName();

    String idOne = UUID.randomUUID().toString();

    Field idField = new Field("document_id",idOne,fieldType);
    Field fileNameField = new Field("file_name", textFileName, fieldType);
    Field contentField = new Field("content",text,fieldType);


    doc.add(idField);
    doc.add(contentField);
    doc.add(fileNameField);

    writer.addDocument(doc);

    analyzer.close();
}

writer.commit();
writer.deleteUnusedFiles();
long endTime = System.currentTimeMillis();

writer.close();

首先,我在上传文件后立即删除文档,然后将更新后的文档编入索引。

1 个答案:

答案 0 :(得分:1)

问题是您的字段在编制索引时正在分析,但您尝试删除的字词已分析。

最好的解决方案是将您想要用作标识符的任何字段用作StringField,这将导致它在没有分析的情况下被编入索引。如:

Field idField = new StringField("document_id", idOne);
doc.add(idField);

或者,你可以使用IndexWriter.deleteDocuments(Query...),并传入一个分析的查询(由QueryParser生成),但在这种情况下你应该注意不要删除比你想要的更多的文档( any < / em>查询找到的文件将被删除,而不仅仅是最佳结果。