Skip to content

Use numeric doc values for Lucene-to-Pinot document ID mapping - #19897

Open
xiangfu0 wants to merge 2 commits into
apache:masterfrom
xiangfu0:xiangfu0/codex1/load-lucene-docids
Open

xiangfu0 wants to merge 2 commits into
apache:masterfrom
xiangfu0:xiangfu0/codex1/load-lucene-docids

Conversation

@xiangfu0

@xiangfu0 xiangfu0 commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

PR flow

Pinot text indexes store document IDs as numeric doc values for efficient mapping, with stored-field fallback.

flowchart TD
  N0["addDocIdFields #40;F1#41;"]:::stAdded
  N1["buildMappingFile #40;F1#41;"]:::stModified
  N2["prepareDocIdTranslator #40;F2#41;"]:::stModified
  N3["createDocIdTranslator #40;F2#41;"]:::stModified
  N4["fillDocIdMapping #40;F2#41;"]:::stAdded
  N0 -->|"writes doc ID fields #8594; reads doc ID fields"| N1
  N2 -->|"calls fillDocIdMapping"| N4
  N3 -->|"calls fillDocIdMapping"| N4
  classDef stAdded fill:#dafbe1,stroke:#1a7f37,color:#1f2328,stroke-width:2px
  classDef stModified fill:#fff8c5,stroke:#9a6700,color:#1f2328,stroke-width:2px
  classDef stRemoved fill:#ffebe9,stroke:#cf222e,color:#1f2328,stroke-width:2px
  classDef stUnchanged fill:#f6f8fa,stroke:#656d76,color:#1f2328,stroke-width:1px
Loading

AI-generated · Green: added · Yellow: modified · Red: removed · Gray: existing

Diff evidence
  • F1: pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/creator/impl/text/LuceneTextIndexCreator.java — before · after
  • F2: pinot-segment-local/src/main/java/org/apache/pinot/segment/local/segment/index/readers/text/LuceneTextIndexReader.java — before · after
  • Regenerate PR flow

New immutable TEXT indexes write Pinot document IDs as numeric doc values, avoiding stored-document decompression when building mappings; old and mixed indexes retain the stored-field fallback.

Usage: rebuild an immutable TEXT index with its existing configuration to write doc values; stored IDs remain available to older readers, and reordered IDs remain correct.

Validation: 16 focused tests and style/license checks passed, including legacy compatibility and reordered document IDs.

@xiangfu0 xiangfu0 added the performance Related to performance optimization label Oct 15, 2026

@xiangfu0 xiangfu0 left a comment •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the Lucene-to-Pinot docId mapping change (correctness, mixed-version compatibility, concurrency). The core approach is sound and well tested.

I verified against Lucene 9.12 source that the MultiDocValues.getNumericValues + monotonic advanceExact(i) loop is correct for the mixed-leaf case: advanceExact sets docID = target before the null-value check, so the forward-only target >= docID() contract is never violated even when a leaf lacks the field, and the merged view uses the same global maxDoc-space ordinals as storedFields().document(i), so both paths address the same document. Forward compatibility also holds: doc values are not stored fields, so an older reader's stored-field iteration (and its single-stored-field assertion) is unaffected by the new index, and a newer reader falls back cleanly on older/mixed indexes. The one standing invariant to keep is no-deletions on the sealed index (maxDoc == numDocs), which is already relied on and guarded elsewhere in the reader.

LGTM — no blocking issues. Two minor, non-blocking consistency nits noted inline on the creator's fallback path. (Posting as a comment rather than a formal Approve because this review is running under the PR author's token, which GitHub does not allow to self-approve.)

@xiangfu0 xiangfu0 added index Related to indexing (general) text-search Related to text/Lucene indexing and search labels Oct 15, 2026
@codecov-commenter

codecov-commenter commented Oct 15, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 0.00%. Comparing base (3101abc) to head (2c07d0f).
⚠️ Report is 1 commits behind head on master.

❗ There is a different number of reports uploaded between BASE (3101abc) and HEAD (2c07d0f). Click for more details.

HEAD has 18 uploads less than BASE
Flag BASE (3101abc) HEAD (2c07d0f)
unittests1 1 0
unittests 2 0
java-25 6 2
temurin 6 2
unittests2 1 0
lane-a 2 1
integration 4 2
integration1 2 0
lane-b 2 1
Additional details and impacted files
@@              Coverage Diff              @@
##             master   #19897       +/-   ##
=============================================
- Coverage     69.37%    0.00%   -69.38%     
=============================================
  Files          3544        3     -3541     
  Lines        233553        6   -233547     
  Branches      37353        0    -37353     
=============================================
- Hits         162030        0   -162030     
+ Misses        59001        6    -58995     
+ Partials      12522        0    -12522     
Flag Coverage Δ
integration 0.00% <ø> (-100.00%) ⬇️
integration1 ?
integration2 0.00% <ø> (ø)
java-25 0.00% <ø> (-69.38%) ⬇️
lane-a 0.00% <ø> (-100.00%) ⬇️
lane-b 0.00% <ø> (ø)
temurin 0.00% <ø> (-69.38%) ⬇️
unittests ?
unittests1 ?
unittests2 ?

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

**Usage:** rebuild an immutable TEXT index with its existing configuration to write doc values; stored IDs remain available to older readers, and reordered IDs remain correct.
**Validation:** 16 focused tests and style/license checks passed, including legacy compatibility and reordered document IDs.
Reproduce: convert a legacy TEXT index with a missing DocID; the conversion now exposes the missing-ID IOException.
Cache StoredFields across fallback rows; 17 focused tests and affected-module checks passed.
@xiangfu0
xiangfu0 force-pushed the xiangfu0/codex1/load-lucene-docids branch from 9e78e98 to 2c07d0f Compare October 15, 2026 23:29

@xiangfu0 xiangfu0 left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-reviewed on the new push (2c07d0f). This revision resolves both minor nits I raised on the previous commit's buildMappingFile:

  • StoredFields is now hoisted and lazily cached once outside the loop instead of being re-created per fallback document, matching the reader's fillDocIdMapping.
  • The fallback now guards a null stored docId and throws a clear IOException("Missing Pinot document id for Lucene document: " + i) before Integer.parseInt, so the creator and reader paths behave consistently on a corrupt index.

It also tightens exception chaining (passing the cause instead of string-concatenating it) and adds testConvertMutableSegmentRejectsMissingStoredDocId, a focused regression test that asserts the new guard fires with the expected root-cause IOException and message.

The core doc-values mapping algorithm is unchanged from the version I verified against Lucene 9.12 source, and the delta is a clean, well-scoped follow-up. LGTM, no outstanding issues. (As before, this is posted as a comment rather than a formal Approve because the review runs under the PR author's token, which GitHub does not allow to self-approve.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

index Related to indexing (general) performance Related to performance optimization text-search Related to text/Lucene indexing and search

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants