目前,我能够将文档列表以及单个文档添加到apache lucene Index中。但是我从索引更新文档时遇到了问题:
我的方法是在文件上载后立即进行操作,因此在写入磁盘之前,我要检查驱动器/文件夹中是否存在文件,并根据文件名删除索引。
其次,我将上传的文件添加到Lucene索引中。
但是我遇到的问题是新添加的以及旧文档都在搜索结果中显示了不同的内容。
例如:文件名为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();
上面首先,我将在文件上传后立即删除文档,然后为更新的文档建立索引。
问题是,当索引正在分析你的领域,但条款,您试图删除与被不进行分析。
最好的解决方案是使要用作该标识符的任何字段都成为a StringField
,这将使该字段无需分析即可被索引。如:
Field idField = new StringField("document_id", idOne);
doc.add(idField);
另外,您也可以使用IndexWriter.deleteDocuments(Query...)
,并传递经过分析的查询(由QueryParser生成),尽管在这种情况下,您应注意不要删除比您想要的更多的文档(查询找到的任何文档都将被删除,而不仅仅是删除最好的结果)。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句