|
15 | 15 | import org.apache.lucene.codecs.Codec;
|
16 | 16 | import org.apache.lucene.codecs.lucene912.Lucene912Codec;
|
17 | 17 | import org.apache.lucene.document.Document;
|
| 18 | +import org.apache.lucene.document.Field; |
18 | 19 | import org.apache.lucene.document.SortedNumericDocValuesField;
|
| 20 | +import org.apache.lucene.document.StringField; |
19 | 21 | import org.apache.lucene.index.DirectoryReader;
|
20 | 22 | import org.apache.lucene.index.IndexWriterConfig;
|
21 | 23 | import org.apache.lucene.index.LeafReaderContext;
|
22 | 24 | import org.apache.lucene.index.SegmentReader;
|
| 25 | +import org.apache.lucene.index.Term; |
23 | 26 | import org.apache.lucene.store.Directory;
|
24 | 27 | import org.apache.lucene.tests.index.BaseDocValuesFormatTestCase;
|
25 | 28 | import org.apache.lucene.tests.index.RandomIndexWriter;
|
|
58 | 61 | import java.util.ArrayList;
|
59 | 62 | import java.util.Collection;
|
60 | 63 | import java.util.Collections;
|
| 64 | +import java.util.HashMap; |
61 | 65 | import java.util.List;
|
| 66 | +import java.util.Map; |
62 | 67 |
|
63 | 68 | import static org.opensearch.common.util.FeatureFlags.STAR_TREE_INDEX;
|
| 69 | +import static org.opensearch.index.compositeindex.CompositeIndexConstants.STAR_TREE_DOCS_COUNT; |
64 | 70 | import static org.opensearch.index.compositeindex.datacube.startree.StarTreeTestUtils.assertStarTreeDocuments;
|
65 | 71 |
|
66 | 72 | /**
|
@@ -207,6 +213,100 @@ public void testStarTreeDocValues() throws IOException {
|
207 | 213 | directory.close();
|
208 | 214 | }
|
209 | 215 |
|
| 216 | + public void testStarTreeDocValuesWithDeletions() throws IOException { |
| 217 | + Directory directory = newDirectory(); |
| 218 | + IndexWriterConfig conf = newIndexWriterConfig(null); |
| 219 | + conf.setMergePolicy(newLogMergePolicy()); |
| 220 | + RandomIndexWriter iw = new RandomIndexWriter(random(), directory, conf); |
| 221 | + |
| 222 | + int iterations = 3; |
| 223 | + Map<String, Integer> map = new HashMap<>(); |
| 224 | + List<String> allIds = new ArrayList<>(); |
| 225 | + for (int iter = 0; iter < iterations; iter++) { |
| 226 | + // Add 10 documents |
| 227 | + for (int i = 0; i < 10; i++) { |
| 228 | + String id = String.valueOf(random().nextInt() + i); |
| 229 | + allIds.add(id); |
| 230 | + Document doc = new Document(); |
| 231 | + doc.add(new StringField("_id", id, Field.Store.YES)); |
| 232 | + int fieldValue = random().nextInt(5) + 1; |
| 233 | + doc.add(new SortedNumericDocValuesField("field", fieldValue)); |
| 234 | + |
| 235 | + int sndvValue = random().nextInt(3); |
| 236 | + |
| 237 | + doc.add(new SortedNumericDocValuesField("sndv", sndvValue)); |
| 238 | + int dvValue = random().nextInt(3); |
| 239 | + |
| 240 | + doc.add(new SortedNumericDocValuesField("dv", dvValue)); |
| 241 | + map.put(sndvValue + "-" + dvValue, fieldValue + map.getOrDefault(sndvValue + "-" + dvValue, 0)); |
| 242 | + iw.addDocument(doc); |
| 243 | + } |
| 244 | + iw.flush(); |
| 245 | + } |
| 246 | + iw.commit(); |
| 247 | + // Delete random number of documents |
| 248 | + int docsToDelete = random().nextInt(9); // Delete up to 9 documents |
| 249 | + for (int i = 0; i < docsToDelete; i++) { |
| 250 | + if (!allIds.isEmpty()) { |
| 251 | + String idToDelete = allIds.remove(random().nextInt(allIds.size() - 1)); |
| 252 | + iw.deleteDocuments(new Term("_id", idToDelete)); |
| 253 | + allIds.remove(idToDelete); |
| 254 | + } |
| 255 | + } |
| 256 | + iw.flush(); |
| 257 | + iw.commit(); |
| 258 | + iw.forceMerge(1); |
| 259 | + iw.close(); |
| 260 | + |
| 261 | + DirectoryReader ir = DirectoryReader.open(directory); |
| 262 | + TestUtil.checkReader(ir); |
| 263 | + assertEquals(1, ir.leaves().size()); |
| 264 | + |
| 265 | + // Assert star tree documents |
| 266 | + for (LeafReaderContext context : ir.leaves()) { |
| 267 | + SegmentReader reader = Lucene.segmentReader(context.reader()); |
| 268 | + CompositeIndexReader starTreeDocValuesReader = (CompositeIndexReader) reader.getDocValuesReader(); |
| 269 | + List<CompositeIndexFieldInfo> compositeIndexFields = starTreeDocValuesReader.getCompositeIndexFields(); |
| 270 | + |
| 271 | + for (CompositeIndexFieldInfo compositeIndexFieldInfo : compositeIndexFields) { |
| 272 | + StarTreeValues starTreeValues = (StarTreeValues) starTreeDocValuesReader.getCompositeIndexValues(compositeIndexFieldInfo); |
| 273 | + StarTreeDocument[] actualStarTreeDocuments = StarTreeTestUtils.getSegmentsStarTreeDocuments( |
| 274 | + List.of(starTreeValues), |
| 275 | + List.of( |
| 276 | + NumberFieldMapper.NumberType.DOUBLE, |
| 277 | + NumberFieldMapper.NumberType.LONG, |
| 278 | + NumberFieldMapper.NumberType.DOUBLE, |
| 279 | + NumberFieldMapper.NumberType.DOUBLE, |
| 280 | + NumberFieldMapper.NumberType.DOUBLE, |
| 281 | + NumberFieldMapper.NumberType.LONG, |
| 282 | + NumberFieldMapper.NumberType.DOUBLE, |
| 283 | + NumberFieldMapper.NumberType.DOUBLE, |
| 284 | + NumberFieldMapper.NumberType.LONG |
| 285 | + ), |
| 286 | + Integer.parseInt(starTreeValues.getAttributes().get(STAR_TREE_DOCS_COUNT)) |
| 287 | + ); |
| 288 | + for (StarTreeDocument starDoc : actualStarTreeDocuments) { |
| 289 | + Long sndvVal = null; |
| 290 | + if (starDoc.dimensions[0] != null) { |
| 291 | + sndvVal = starDoc.dimensions[0]; |
| 292 | + } |
| 293 | + Long dvVal = null; |
| 294 | + if (starDoc.dimensions[1] != null) { |
| 295 | + dvVal = starDoc.dimensions[1]; |
| 296 | + } |
| 297 | + if (starDoc.metrics[0] != null) { |
| 298 | + double metric = (double) starDoc.metrics[0]; |
| 299 | + if (map.containsKey(sndvVal + "-" + dvVal)) { |
| 300 | + assertEquals((long) map.get(sndvVal + "-" + dvVal), (long) metric); |
| 301 | + } |
| 302 | + } |
| 303 | + } |
| 304 | + } |
| 305 | + } |
| 306 | + ir.close(); |
| 307 | + directory.close(); |
| 308 | + } |
| 309 | + |
210 | 310 | private XContentBuilder getExpandedMapping() throws IOException {
|
211 | 311 | return topMapping(b -> {
|
212 | 312 | b.startObject("composite");
|
|
0 commit comments