- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我的项目围绕 Lucene 6.6.0 展开。实际上,它涉及一个用 java 编写的桌面搜索引擎,其中搜索部分与索引部分位于单独的应用程序中。有时我必须向索引添加新字段以满足客户需求,而不必重新索引(即解析文件+索引)所有内容。
因此,当应用程序启动时,我使用 IndexWriter,打开与其关联的 IndexReader :
IndexReader reader = DirectoryReader.open(writer, true, false);
然后对于索引中已存在的每个文档:
StoredField fieldVersion = new StoredField(
FIELDNAME_VERSION,
fixedValue // The value is the same for all the documents but may change (for all documents) when upgrading the version.
);
for (int i = 0; i < idMax; i++) {
Document currentDoc = reader.document(i);
// Checks if the field exists in the index
if (
// Field does not exist yet
currentDoc.get(FIELDNAME_VERSION) == null ||
// Field value is different from what it should be
!currentDoc.get(FIELDNAME_VERSION).contentEquals(fixedValue))
{
// THe field does not exist so we add it to the doc and beforehand removes the field from the currentDoc (also tried without removing first with the same result)
currentDoc.removeField(FIELDNAME_VERSION);
currentDoc.add(fieldVersion);
// Updates the document in the index
writer.updateDocuments(
new Term(FIELDNAME_PATH, currentDoc.get(FIELDNAME_PATH),
currentDoc);
// also tried with
writer.deleteDocuments(new Term(FIELDNAME_PATH,
currentDoc.get(FIELDNAME_PATH)));
writer.addDocument(currentDoc);
}
}
// When all documents have been checked, write the index
writer.commit();
当我第一次运行此字段时,该字段会按预期添加到所有没有该字段的文档中。问题是,当fixedValue更改时,新文档会添加到索引中,而我希望currentDoc更新其fieldVersion,而不是创建另一个文档,其值与除fieldVersion之外的所有字段的原始值相同。
IndexWriter 处于追加模式(也尝试使用追加或创建)。如果我首先索引单个文件,我会在索引中得到 1 个文档,然后在索引更新后,我会得到 2 个文档,然后是 4 个,然后是 8 个,然后是 16 个,...始终引用同一个文件(仅 fieldVersion有不同的内容)。
This other SO question没有帮助我。
当我要求 Lucene 更新现有文档时,为什么 Lucene 添加新文档?应该采取什么措施来解决此问题(即用相同的文档替换现有文档,只需使用不同的 fieldVersion 内容?
编辑 1:
调用此方法后,似乎缺少一个字段。该字段通过以下方式初始化:
new TextField(FIELDNAME_UNSTORED,
"",
Field.Store.NO);
所以它没有被存储。
与FIELDNAME_PATH关联的字段初始化为
StringField pathField = new StringField(FIELDNAME_PATH,
"",
Field.Store.YES);
编辑2:
我实际上没有得到的是,如果我只执行 deleteDocuments(new Term(...))
那么所有文档都会从索引中删除(如预期),但是如果我添加删除 add(currentDoc)
之后,我得到的文档数量是原来的两倍。就好像该文档在其原始版本中添加了一次,在其更新版本中添加了第二次。
解决方案:
正如 @femtoRgon 所指出的,路径字段在索引过程中没有被标记化。但后来它被自动标记化了。因此,解决方案是在索引期间重新创建路径字段(以及其他字段),使用临时 Document
来存储字段,然后使用此 updateDocument()
临时文档
。
非常感谢任何帮助!
最佳答案
lucene中的更新总是添加一个新文档,它只是先删除与给定术语匹配的所有文档,并且无论是否找到要删除的文档,它都会愉快地添加新文档。因此,无论出于何种原因,您都无法在该术语上找到匹配项。您尚未展示如何对 FIELDNAME_PATH
进行索引,但对于此处的模式,应该对其进行索引而不是标记化(即使用 StringField
)。
您只需运行 TermQuery
即可测试传递给更新的术语是否有效。如果您从 TermQuery 得到 0 个结果,则 IndexWriter.UpdateDocuments
也不会找到要删除的文档。
就缺少未存储字段而言,是的,您在此处使用的模式无法很好地处理未存储字段。未存储的字段不包含在从 IndexReader.document
返回的文档中(这就是存储字段的目的,以便可以从索引中检索它)。因此,由于结果中缺少该值,因此您传递到更新的文档中仍然会缺少该值,除非您以其他方式重新创建该值。要么从您正在使用的任何源 Material 重建文档,要么确保存储您想要在更新中保留的任何内容。
关于java - Lucene 不断添加文档,而使用 updateDocument,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51226749/
如果这不是一个错误,那就是另一个错误。如果不是那样的话,那就是别的东西了。我觉得我的项目已经改变了很多,现在只是试图解决代码签名问题,结果一切都搞砸了。我严格按照说明进行操作,但出现错误,例如当前的“
我不确定是否有一些我不知道的内置变量或规则,或者 make 是否有问题,或者我只是疯了。 对于我的一个项目,我有一个如下的 makefile: CC=g++ CFLAGS=-O3 `libpng-co
我有大约 10 个 div,它们必须不断翻转,每个 div 延迟 3 秒 这个 codrops 链接的最后一个效果是我正在寻找的,但无需单击 div http://tympanus.net/Devel
我如何使用 jQuery 持续运行 PHP 脚本并每秒获取响应,以及将鼠标上的少量数据发送到同一脚本? 我真的必须添加一些随机扩展才能让这么简单的计时器工作吗? 最佳答案 To iterate is
JBoss 4.x EJB 3.0 我见过如下代码(大大简化): @Stateless @TransactionAttribute(TransactionAttributeType.NOT_SUPPO
使用 PHPStorm,我试图忽略每次尝试进行 git 提交时 pop 的 workspace.xml。 我的 .gitignore 看起来像: /.idea/ .idea/workspace.xml
我是一名优秀的程序员,十分优秀!