From 28b9f2ef19062b7fd8551bdde4d88debd218cc59 Mon Sep 17 00:00:00 2001 From: Simon Willnauer Date: Tue, 16 Jan 2024 10:53:43 +0100 Subject: [PATCH] Prevent parent field from added to existing index (#13016) This change prevents users from adding a parent field to an existing index. Parent field must be added before any documents are added to the index to prevent documents without the parent field from being indexed and later to be treated as child documents upon merge. Relates to #12829 --- .../org/apache/lucene/index/IndexWriter.java | 7 +++- .../apache/lucene/index/TestIndexWriter.java | 42 +++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/lucene/core/src/java/org/apache/lucene/index/IndexWriter.java b/lucene/core/src/java/org/apache/lucene/index/IndexWriter.java index 79d933798688..89e8bcafd757 100644 --- a/lucene/core/src/java/org/apache/lucene/index/IndexWriter.java +++ b/lucene/core/src/java/org/apache/lucene/index/IndexWriter.java @@ -1121,6 +1121,12 @@ public IndexWriter(Directory d, IndexWriterConfig conf) throws IOException { // NOTE: this is correct even for an NRT reader because we'll pull FieldInfos even for the // un-committed segments: globalFieldNumberMap = getFieldNumberMap(); + if (create == false + && conf.getParentField() != null + && globalFieldNumberMap.getFieldNames().contains(conf.getParentField()) == false) { + throw new IllegalArgumentException( + "can't add a parent field to an already existing index without a parent field"); + } validateIndexSort(); @@ -1272,7 +1278,6 @@ private FieldNumbers getFieldNumberMap() throws IOException { map.addOrGet(fi); } } - return map; } diff --git a/lucene/core/src/test/org/apache/lucene/index/TestIndexWriter.java b/lucene/core/src/test/org/apache/lucene/index/TestIndexWriter.java index f4ef189112a4..aea989720de0 100644 --- a/lucene/core/src/test/org/apache/lucene/index/TestIndexWriter.java +++ b/lucene/core/src/test/org/apache/lucene/index/TestIndexWriter.java @@ -4943,6 +4943,48 @@ public void testParentAndSoftDeletesAreTheSame() throws IOException { } } + public void testParentFieldExistingIndex() throws IOException { + try (Directory dir = newDirectory()) { + IndexWriterConfig iwc = new IndexWriterConfig(new MockAnalyzer(random())); + try (IndexWriter writer = new IndexWriter(dir, iwc)) { + writer.addDocument(new Document()); + } + IllegalArgumentException iae = + expectThrows( + IllegalArgumentException.class, + () -> + new IndexWriter( + dir, + new IndexWriterConfig(new MockAnalyzer(random())) + .setOpenMode(OpenMode.APPEND) + .setParentField("foo"))); + assertEquals( + "can't add a parent field to an already existing index without a parent field", + iae.getMessage()); + iae = + expectThrows( + IllegalArgumentException.class, + () -> + new IndexWriter( + dir, + new IndexWriterConfig(new MockAnalyzer(random())) + .setOpenMode(OpenMode.CREATE_OR_APPEND) + .setParentField("foo"))); + assertEquals( + "can't add a parent field to an already existing index without a parent field", + iae.getMessage()); + + try (IndexWriter writer = + new IndexWriter( + dir, + new IndexWriterConfig(new MockAnalyzer(random())) + .setOpenMode(OpenMode.CREATE) + .setParentField("foo"))) { + writer.addDocument(new Document()); + } + } + } + public void testIndexWithParentFieldIsCongruent() throws IOException { try (Directory dir = newDirectory()) { IndexWriterConfig iwc = new IndexWriterConfig(new MockAnalyzer(random()));