Generalize document clustering fingerprints - #6651
Open
Mallets wants to merge 7 commits into
Open
Conversation
Support ordered fingerprint policies, recursive multi-level clustering, and JSON path exclusions so document clustering config is no longer limited to the fixed schema/grouping shape. Co-authored-by: Cursor <cursoragent@cursor.com>
Keep the benchmark evidence in the PR description while avoiding a permanent synthetic bench target in the crate. Co-authored-by: Cursor <cursoragent@cursor.com>
Move cluster-size observation into the clusterer so recursive traversal stays allocation-free and mapping validation remains owned by Tantivy. Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Mallets
marked this pull request as ready for review
August 3, 2026 12:52
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
JsonPathhandling for raw/tokenized paths and structure exclusions.DocIdClustererto a recursive fingerprint-prefix tree that emits largest groups first at every fingerprint level.Motivation
This change makes document clustering implement what the configuration already allows expressing: an ordered list of fingerprint policies rather than a fixed (schema, grouping) pair.
Each policy produces an independent hash from its configured fields. These hashes form successive clustering levels:
At every level, sibling clusters are emitted largest first before recursively ordering their children. Each level can use a different hashing policy, e.g. structure, tokenized message shape, and service name.
The previous implementation collapsed this configuration into exactly two steps. The new implementation preserves every configured step and supports arbitrary fingerprint depth.
Validation
cargo +nightly fmt --allcargo test -p quickwit-indexing docs_clustering::clusterer --libcargo test -p quickwit-indexing docs_clustering --libcargo clippy -p quickwit-indexing --all-features --testsBenchmark
All benchmarks used 100k synthetic documents.
Melem/sdenotes millions of documents processed per second.The
mainbaseline runs the fixed two-level fingerprinter and clusterer. Fingerprints are precomputed for insertion and sorting benchmarks. Sorting receives fully built clusterers through Criterion's untimed setup and measures sorting/finalization, including construction and validation of the finalDocIdMapping.main8.20 Melem/s8.11 Melem/s121.86 Melem/s71.29 Melem/s38.40 Melem/s28.55 Melem/s268.50 Melem/s605.57 Melem/s185.37 Melem/s206.11 Melem/sThe recursive representation makes insertion slower than the specialized fixed two-level implementation, but sorting/finalization is substantially faster for low-cardinality clusters and about 11% faster for high-cardinality clusters. Fingerprint calculation is effectively unchanged.
By default, insertion is limited to 4 MiB per shard, and actual indexing throughput is far below tens of millions of documents per second. The measured insertion rates therefore leave substantial headroom and are unlikely to be the limiting factor. Sorting/finalization time is more performance-critical, and that phase improves with the recursive design.