Add updateDocuments API which accept a query (reopen) (#12346)

This commit is contained in:
Patrick Zhai 2023-06-03 20:16:16 -07:00 committed by GitHub
parent 52ace7eb35
commit 0c293909c0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 50 additions and 2 deletions

View File

@ -130,6 +130,9 @@ API Changes
* GITHUB#12268: Add BitSet.clear() without parameters for clearing the entire set * GITHUB#12268: Add BitSet.clear() without parameters for clearing the entire set
(Jonathan Ellis) (Jonathan Ellis)
* GITHUB#12346: add new IndexWriter#updateDocuments(Query, Iterable<Document>) API
to update documents atomically, with respect to refresh and commit using a query. (Patrick Zhai)
New Features New Features
--------------------- ---------------------

View File

@ -142,6 +142,10 @@ final class DocumentsWriterDeleteQueue implements Accountable, Closeable {
return new TermNode(term); return new TermNode(term);
} }
static Node<Query> newNode(Query query) {
return new QueryNode(query);
}
static Node<DocValuesUpdate[]> newNode(DocValuesUpdate... updates) { static Node<DocValuesUpdate[]> newNode(DocValuesUpdate... updates) {
return new DocValuesUpdatesNode(updates); return new DocValuesUpdatesNode(updates);
} }
@ -437,6 +441,23 @@ final class DocumentsWriterDeleteQueue implements Accountable, Closeable {
} }
} }
private static final class QueryNode extends Node<Query> {
QueryNode(Query query) {
super(query);
}
@Override
void apply(BufferedUpdates bufferedDeletes, int docIDUpto) {
bufferedDeletes.addQuery(item, docIDUpto);
}
@Override
public String toString() {
return "del=" + item;
}
}
private static final class QueryArrayNode extends Node<Query[]> { private static final class QueryArrayNode extends Node<Query[]> {
QueryArrayNode(Query[] query) { QueryArrayNode(Query[] query) {
super(query); super(query);

View File

@ -1521,6 +1521,19 @@ public class IndexWriter
delTerm == null ? null : DocumentsWriterDeleteQueue.newNode(delTerm), docs); delTerm == null ? null : DocumentsWriterDeleteQueue.newNode(delTerm), docs);
} }
/**
* Similar to {@link #updateDocuments(Term, Iterable)}, but take a query instead of a term to
* identify the documents to be updated
*
* @lucene.experimental
*/
public long updateDocuments(
Query delQuery, Iterable<? extends Iterable<? extends IndexableField>> docs)
throws IOException {
return updateDocuments(
delQuery == null ? null : DocumentsWriterDeleteQueue.newNode(delQuery), docs);
}
private long updateDocuments( private long updateDocuments(
final DocumentsWriterDeleteQueue.Node<?> delNode, final DocumentsWriterDeleteQueue.Node<?> delNode,
Iterable<? extends Iterable<? extends IndexableField>> docs) Iterable<? extends Iterable<? extends IndexableField>> docs)

View File

@ -3476,7 +3476,12 @@ public class TestIndexWriter extends LuceneTestCase {
Document doc = new Document(); Document doc = new Document();
doc.add(new StringField("id", id, Field.Store.YES)); doc.add(new StringField("id", id, Field.Store.YES));
if (mixDeletes && random().nextBoolean()) { if (mixDeletes && random().nextBoolean()) {
writer.updateDocuments(new Term("id", id), Arrays.asList(doc, doc)); if (random().nextBoolean()) {
writer.updateDocuments(new Term("id", id), Arrays.asList(doc, doc));
} else {
writer.updateDocuments(
new TermQuery(new Term("id", id)), Arrays.asList(doc, doc));
}
} else { } else {
writer.softUpdateDocuments( writer.softUpdateDocuments(
new Term("id", id), new Term("id", id),

View File

@ -39,6 +39,7 @@ import org.apache.lucene.index.TieredMergePolicy;
import org.apache.lucene.internal.tests.IndexWriterAccess; import org.apache.lucene.internal.tests.IndexWriterAccess;
import org.apache.lucene.internal.tests.TestSecrets; import org.apache.lucene.internal.tests.TestSecrets;
import org.apache.lucene.search.Query; import org.apache.lucene.search.Query;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.store.Directory; import org.apache.lucene.store.Directory;
import org.apache.lucene.tests.analysis.MockAnalyzer; import org.apache.lucene.tests.analysis.MockAnalyzer;
import org.apache.lucene.tests.util.LuceneTestCase; import org.apache.lucene.tests.util.LuceneTestCase;
@ -283,7 +284,12 @@ public class RandomIndexWriter implements Closeable {
w.softUpdateDocuments( w.softUpdateDocuments(
delTerm, docs, new NumericDocValuesField(config.getSoftDeletesField(), 1)); delTerm, docs, new NumericDocValuesField(config.getSoftDeletesField(), 1));
} else { } else {
seqNo = w.updateDocuments(delTerm, docs); if (r.nextInt(10) < 3) {
// 30% chance
seqNo = w.updateDocuments(new TermQuery(delTerm), docs);
} else {
seqNo = w.updateDocuments(delTerm, docs);
}
} }
maybeFlushOrCommit(); maybeFlushOrCommit();
return seqNo; return seqNo;