xiangfu0 commented on code in PR #19897:
URL: https://github.com/apache/pinot/pull/19897#discussion_r4365815040


##########
pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/creator/impl/text/LuceneTextIndexCreator.java:
##########
@@ -331,6 +313,17 @@ public void add(String[] documents, int length) {
     }
   }
 
+  private void addDocIdFields(Document document) {
+    int docId = _nextDocId++;
+    // Keep the stored field for older readers. Immutable indexes add doc 
values to avoid decompressing every stored
+    // document on segment load and retain the actual Pinot id when Lucene 
flushes or merges reorder documents.
+    document.add(new StoredField(PINOT_DOC_ID_STORED_FIELD_NAME, docId));
+    // A TEXT column with this name must keep the stored-field fallback to 
avoid conflicting Lucene field schemas.
+    if (_commitOnClose && 
!_textColumn.equals(PINOT_DOC_ID_DOC_VALUES_FIELD_NAME)) {

Review Comment:
   Fixed in 
[485c9696f9](https://github.com/apache/pinot/commit/485c9696f9cd7e99271726b9d36ffabceb3cdaa6).
 The creator now omits numeric doc values for storeInSegmentFile=true, and for 
explicit Skip mode. The default uncombined path retains the first-mapping 
optimization and its documented storage tradeoff. Updated the description to 
scope the benchmark and usage accordingly; no new configuration option.



##########
pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/store/TextIndexUtils.java:
##########
@@ -89,6 +95,63 @@ public void onChange(Set<String> changedConfigs, Map<String, 
String> clusterConf
     }
   }
 
+  /// Reads the actual Pinot ids after Lucene merges and sorting, optionally 
remapping mutable ids during conversion.
+  /// Doc values avoid stored-field decompression. Mutable indexes contain 
only the stored field; older immutable
+  /// indexes and documents without doc values also use the per-document 
stored-field fallback.
+  /// Returns whether the final mapping is the identity mapping.
+  public static boolean fillDocIdMapping(IndexReader indexReader, 
PinotDataBuffer buffer, int numDocs,
+      @Nullable int[] mutableToImmutableDocIdMap)
+      throws IOException {
+    NumericDocValues pinotDocIdValues =
+        MultiDocValues.getNumericValues(indexReader, 
LuceneTextIndexCreator.PINOT_DOC_ID_DOC_VALUES_FIELD_NAME);
+    PinotDocIdVisitor visitor = new PinotDocIdVisitor();
+    StoredFields storedFields = null;
+    boolean isIdentityMapping = true;
+    for (int luceneDocId = 0; luceneDocId < numDocs; luceneDocId++) {
+      int pinotDocId;
+      if (pinotDocIdValues != null && 
pinotDocIdValues.advanceExact(luceneDocId)) {
+        pinotDocId = Math.toIntExact(pinotDocIdValues.longValue());
+      } else {
+        if (storedFields == null) {
+          storedFields = indexReader.storedFields();
+        }
+        visitor._pinotDocId = Integer.MIN_VALUE;
+        storedFields.document(luceneDocId, visitor);
+        pinotDocId = visitor._pinotDocId;
+        if (pinotDocId == Integer.MIN_VALUE) {
+          throw new IOException("Missing Pinot document id for Lucene 
document: " + luceneDocId);
+        }
+      }
+      if (mutableToImmutableDocIdMap != null) {
+        // Conversion can reorder Pinot rows independently of Lucene's own 
document order.
+        pinotDocId = mutableToImmutableDocIdMap[pinotDocId];
+      }
+      isIdentityMapping &= luceneDocId == pinotDocId;
+      buffer.putInt((long) luceneDocId * Integer.BYTES, pinotDocId);
+    }
+    return isIdentityMapping;

Review Comment:
   Fixed in 
[485c9696f9](https://github.com/apache/pinot/commit/485c9696f9cd7e99271726b9d36ffabceb3cdaa6).
 The creator now consumes the shared helper's identity result after 
mutable-to-immutable remapping. In explicit TryOptimize it closes the temporary 
mapping buffer, deletes an identity mapping, and persists Skip before combining 
files. Default/unspecified modes retain their mapping; a nonidentity 
TryOptimize mapping is retained with Default. Added persisted-mode and 
query-result coverage, including mappings made identity or nonidentity by 
remapping.



##########
pinot-segment-local/src/test/java/org/apache/pinot/segment/local/segment/index/creator/LuceneTextIndexCreatorTest.java:
##########
@@ -111,9 +118,84 @@ public void testIndexWriterReaderMatchWithOrClause()
     // Use TextIndex reader to validate that reads work
     try (LuceneTextIndexReader reader = new LuceneTextIndexReader("foo", 
INDEX_DIR, 5, new HashMap<>())) {
       int[] matchedDocIds = reader.getDocIds("retain|keep").toArray();
-      Assert.assertEquals(matchedDocIds.length, 2);
-      Assert.assertEquals(matchedDocIds[0], 1);
-      Assert.assertEquals(matchedDocIds[1], 2);
+      assertEquals(matchedDocIds.length, 2);
+      assertEquals(matchedDocIds[0], 1);
+      assertEquals(matchedDocIds[1], 2);
+    }
+  }
+
+  @Test
+  public void testDocValuesRetainStoredIdsForSingleAndMultiValueDocuments()

Review Comment:
   Added in 
[485c9696f9](https://github.com/apache/pinot/commit/485c9696f9cd7e99271726b9d36ffabceb3cdaa6):
 real storeInSegmentFile=true combined indexes exercise persisted 
mapping/config and LuceneTextIndexBufferReader queries across unspecified, 
Default, TryOptimize, and Skip modes. A legacy stored-only combined file has no 
mapping buffer and its source directory is removed; permuted-ID query results 
verify the fallback mapping is rebuilt from the combined buffer. Targeted tests 
and required checks passed.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to