fix(fts): do not count empty documents in num_docs#7745
Conversation
📝 WalkthroughWalkthroughChangesFTS Empty Document Handling
Estimated code review effort: 2 (Simple) | ~10 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@rust/lance/src/dataset/tests/dataset_index.rs`:
- Around line 408-418: Replace the manual schema, RecordBatch, and StringArray
construction in the modified test fixture with the repository’s record_batch!()
helper, preserving the existing string values and resulting batch data.
- Around line 405-416: Add a dedicated regression case alongside the existing
mixed-token fixture that builds an index exclusively from empty and
whitespace-only strings, then assert the resulting BM25/statistics metadata
reports num_docs == 0. Keep the existing mixed-document coverage unchanged and
target the dataset index test’s index-building and statistics assertions.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 20035755-89a9-431d-8657-c3fd83cd10b7
📒 Files selected for processing (2)
rust/lance-index/src/scalar/inverted/builder.rsrust/lance/src/dataset/tests/dataset_index.rs
| // Mix documents that produce tokens with ones that tokenize to nothing | ||
| // (empty and whitespace-only strings). The latter carry no searchable | ||
| // content and must not be counted in `num_docs`. | ||
| let batches: Vec<RecordBatch> = vec![ | ||
| RecordBatch::try_new( | ||
| schema.clone(), | ||
| vec![Arc::new(StringArray::from(vec!["", "", ""]))], | ||
| vec![Arc::new(StringArray::from(vec![ | ||
| "lance", | ||
| "", | ||
| "lance database", | ||
| " ", | ||
| ]))], |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Map the relevant test file and inspect surrounding tests for index coverage.
git ls-files rust/lance/src/dataset/tests/dataset_index.rs
wc -l rust/lance/src/dataset/tests/dataset_index.rs
sed -n '1,520p' rust/lance/src/dataset/tests/dataset_index.rs | cat -n | sed -n '1,520p'
# Search for all token/index-related assertions in this file.
rg -n "num_docs|empty|whitespace|token|search|index" rust/lance/src/dataset/tests/dataset_index.rsRepository: lance-format/lance
Length of output: 43487
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Check whether any other test asserts FTS statistics for zero-token / empty-index behavior.
rg -n "num_docs|empty index|empty_table|empty strings|tokenize to nothing|no search hits|full_text_search" rust/lance/src/dataset/tests/dataset_index.rs
# Inspect the nearby FTS tests around the empty-index cases.
sed -n '1210,1295p' rust/lance/src/dataset/tests/dataset_index.rs | cat -n
sed -n '244,280p' rust/lance/src/dataset/tests/dataset_index.rs | cat -nRepository: lance-format/lance
Length of output: 9394
Add an all-empty regression case.
The empty-table search path is already covered, but this fixture still doesn’t assert the num_docs == 0 BM25/statistics path. Keep a dedicated case for an index built only from empty/whitespace strings if that behavior is part of the regression target.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@rust/lance/src/dataset/tests/dataset_index.rs` around lines 405 - 416, Add a
dedicated regression case alongside the existing mixed-token fixture that builds
an index exclusively from empty and whitespace-only strings, then assert the
resulting BM25/statistics metadata reports num_docs == 0. Keep the existing
mixed-document coverage unchanged and target the dataset index test’s
index-building and statistics assertions.
| let batches: Vec<RecordBatch> = vec![ | ||
| RecordBatch::try_new( | ||
| schema.clone(), | ||
| vec![Arc::new(StringArray::from(vec!["", "", ""]))], | ||
| vec![Arc::new(StringArray::from(vec![ | ||
| "lance", | ||
| "", | ||
| "lance database", | ||
| " ", | ||
| ]))], | ||
| ) | ||
| .unwrap(), |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win
Use record_batch!() for the modified fixture.
The changed test still manually constructs the schema, RecordBatch, and StringArray; repository guidance requires record_batch!() instead of this boilerplate.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@rust/lance/src/dataset/tests/dataset_index.rs` around lines 408 - 418,
Replace the manual schema, RecordBatch, and StringArray construction in the
modified test fixture with the repository’s record_batch!() helper, preserving
the existing string values and resulting batch data.
Source: Coding guidelines
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Closes #7660
Follow-up to #7656. Empty and whitespace-only string documents tokenize to nothing but were still appended to the inverted index, inflating
num_docsand skewing BM25 document-count statistics. #7656 introduced skip-empty behavior for list-string documents via askip_empty_documentflag; the plain-string path still passedfalse.Since both call sites should now skip zero-token documents, this removes the flag and makes
IndexWorker::process_documentunconditionally skip when a document produces no tokens, unifying string and list behavior.Verified locally:
test_create_fts_index_with_empty_strings(strengthened to assertnum_docs),cargo fmt, andcargo clippy --features protoc --tests -- -D warningsall pass.Summary by CodeRabbit