Cross Index Query¶
A query that filters the primary index to documents whose join key matches documents in a secondary index. Uses Lucene’s JoinUtil internally. The query runs on the secondary index; matching values of secondary_field are collected eagerly and used to build a TermsQuery on primary_field in the primary index. The secondary index searcher is acquired only during query construction and released immediately afterward — it is not held open during primary search execution.
Both primary_field and secondary_field must exist in their respective indices. The secondary index must be on the same nrtsearch node. The query field is required. If any of these are missing or invalid, an error is returned.
Nested cross-index queries are supported: the inner query may itself contain a CrossIndexQuery referencing a third index.
The score_mode controls how scores from matching secondary documents are aggregated and propagated to the primary index results:
JOIN_SCORE_NONE- No scoring; acts as a pure filter (default)
JOIN_SCORE_AVG- Average score of matching secondary documents
JOIN_SCORE_MAX- Maximum score of matching secondary documents
JOIN_SCORE_MIN- Minimum score of matching secondary documents
JOIN_SCORE_TOTAL- Sum of scores of matching secondary documents
When used inside a BooleanQuery FILTER clause, the cross-index query filters without contributing to the score regardless of score_mode.
Memory considerations¶
JoinUtil collects all unique join-key values from matching secondary documents into an in-memory hash set. For large secondary result sets this can consume significant memory. Use the max_terms field to set an upper bound on the number of matching secondary documents allowed. If the inner query matches more documents than this limit, an error is returned instead of risking excessive memory usage.
Multi-valued join fields¶
If the secondary join field is registered with multiValued: true, this is automatically detected from the field definition and handled correctly by JoinUtil. No additional configuration is needed.
Proto definition:
message CrossIndexQuery {
enum JoinScoreMode {
JOIN_SCORE_UNSET = 0; // Unset — treated as JOIN_SCORE_NONE (filter only)
JOIN_SCORE_NONE = 1; // No scoring - filter only
JOIN_SCORE_AVG = 2; // Average score of matching secondary documents
JOIN_SCORE_MAX = 3; // Maximum score of matching secondary documents
JOIN_SCORE_MIN = 4; // Minimum score of matching secondary documents
JOIN_SCORE_TOTAL = 5; // Sum of scores of matching secondary documents
}
string index = 1; // Name of the secondary index (must be on the same nrtsearch node)
string primary_field = 2; // Field in the primary index containing the join key
string secondary_field = 3; // Field in the secondary index containing the join key
Query query = 4; // Query to execute on the secondary index (required)
JoinScoreMode score_mode = 5; // Score aggregation mode (default: JOIN_SCORE_NONE)
uint32 max_terms = 6; // Max matching secondary docs allowed; 0 = unlimited (default: 0)
}