Update and delete
Delete by query
writer.DeleteDocuments(new TermQuery("id", "abc-123"));
writer.Commit();
Deletes are buffered and applied at commit time.
Update (delete-then-add)
var doc = new LeanDocument();
doc.Add(new StringField("id", "abc-123"));
doc.Add(new TextField("body", "Updated content"));
writer.UpdateDocument(new TermQuery("id", "abc-123"), doc);
writer.Commit();
The delete and add land in the same commit. Readers never see a window where the document is missing.
Update by query
var replacement = new LeanDocument();
replacement.Add(new StringField("id", "abc-123"));
replacement.Add(new TextField("body", "Replacement content"));
writer.UpdateDocuments(new TermQuery("id", "abc-123"), replacement);
writer.Commit();
UpdateDocuments accepts any Query, not just TermQuery.
Sequence numbers
Track document versions for change-data-capture and replication:
var config = new IndexWriterConfig
{
TrackSequenceNumbers = true,
};
// Each commit gets a monotonically increasing sequence number
long seq = writer.NextSequenceNumber;
writer.Commit();
Sequence numbers are persisted through commits and merges. Use them to identify which documents changed between two points in time, or to resume a replication stream from a known position.
Soft deletes
Mark documents deleted without immediately removing them:
var config = new IndexWriterConfig
{
SoftDeletesEnabled = true,
SoftDeleteRetentionSeconds = TimeSpan.FromHours(24).TotalSeconds,
};
writer.SoftDeleteDocuments(new TermQuery("id", "abc-123"));
writer.Commit();
Soft-deleted documents are excluded from results but retained until the retention period expires and a merge reclaims them.
AddIndexes
Merge segments from another index without re-analysing:
var sourceDir = new MMapDirectory("/path/to/other/index");
writer.AddIndexes(sourceDir);
writer.Commit();
Useful for restoring archived segments, merging partitioned indexes, or bootstrapping from a snapshot.
Two-phase commit
PrepareCommit() stages all pending changes without making them visible to readers:
writer.AddDocument(doc1);
writer.AddDocument(doc2);
writer.PrepareCommit();
// Changes are staged but not visible yet.
// Rollback() would discard them.
writer.Commit(); // Makes the staged changes visible
Use PrepareCommit() when you need atomic visibility: add several documents, stage the commit, then either publish or roll back as a unit. Readers never see a partial batch.
ForceMerge
Reduce the number of segments in the index:
writer.ForceMerge(maxSegments: 1);
ForceMerge consolidates segments down to maxSegments. A single-segment merge eliminates all deleted documents and produces the smallest possible index. Merges are I/O-intensive — call during maintenance windows, not on every commit.