Advanced query resolution system for complex boolean operations and result manipulation. The Resolver class enables sophisticated search scenarios requiring logical operations, result boosting, and custom scoring algorithms.
Advanced query resolver that processes intermediate search results and applies boolean logic operations.
/**
* Advanced query resolver for complex search operations and boolean logic
* @param options - Resolver configuration options or initial search results
*/
class Resolver<
D extends DocumentData = undefined,
W extends WorkerType = false,
S extends StorageInterface | boolean = false,
H extends HighlightOptions | boolean = false,
R extends boolean = false,
E extends boolean = H extends false ? false : true,
A extends boolean = false
> {
constructor(options?: ResolverOptions<D, W, S, H, R, E, A> | IntermediateSearchResults);
/** Current intermediate search results */
result: IntermediateSearchResults;
}Perform logical operations on search results to create complex query combinations.
/**
* Perform AND operation on search results (intersection)
* @param args - Search results or queries to intersect
* @returns Resolver instance for chaining with proper type propagation
*/
and<
d extends DocumentData = D,
h extends HighlightOptions | boolean = H,
r extends boolean = R,
e extends boolean = h extends HighlightOptions ? true : E,
a extends boolean = A
>(...args: ResolverOptions<d, W, S, h, r, e, a>[]):
DocumentSearchResultsWrapper<d, W, S, h, true, r, e, false, a>;
/**
* Perform OR operation on search results (union)
* @param args - Search results or queries to combine
* @returns Resolver instance for chaining with proper type propagation
*/
or<
d extends DocumentData = D,
h extends HighlightOptions | boolean = H,
r extends boolean = R,
e extends boolean = h extends HighlightOptions ? true : E,
a extends boolean = A
>(...args: ResolverOptions<d, W, S, h, r, e, a>[]):
DocumentSearchResultsWrapper<d, W, S, h, true, r, e, false, a>;
/**
* Perform XOR operation on search results (exclusive or)
* @param args - Search results or queries for exclusive combination
* @returns Resolver instance for chaining with proper type propagation
*/
xor<
d extends DocumentData = D,
h extends HighlightOptions | boolean = H,
r extends boolean = R,
e extends boolean = h extends HighlightOptions ? true : E,
a extends boolean = A
>(...args: ResolverOptions<d, W, S, h, r, e, a>[]):
DocumentSearchResultsWrapper<d, W, S, h, true, r, e, false, a>;
/**
* Perform NOT operation on search results (exclusion)
* @param args - Search results or queries to exclude
* @returns Resolver instance for chaining with proper type propagation
*/
not<
d extends DocumentData = D,
h extends HighlightOptions | boolean = H,
r extends boolean = R,
e extends boolean = h extends HighlightOptions ? true : E,
a extends boolean = A
>(...args: ResolverOptions<d, W, S, h, r, e, a>[]):
DocumentSearchResultsWrapper<d, W, S, h, true, r, e, false, a>;Usage Examples:
import { Index, Resolver } from "flexsearch";
// Create multiple indexes for different content types
const titleIndex = new Index();
const contentIndex = new Index();
const tagIndex = new Index();
// Add content to indexes
titleIndex.add(1, "JavaScript Programming Guide");
titleIndex.add(2, "Python Web Development");
titleIndex.add(3, "JavaScript Framework Comparison");
contentIndex.add(1, "Learn JavaScript fundamentals and advanced concepts");
contentIndex.add(2, "Build web applications with Python and Django");
contentIndex.add(3, "React vs Vue vs Angular framework analysis");
tagIndex.add(1, "javascript programming tutorial");
tagIndex.add(2, "python web backend");
tagIndex.add(3, "javascript frontend frameworks");
// Search each index
const titleResults = titleIndex.search("javascript");
const contentResults = contentIndex.search("javascript");
const tagResults = tagIndex.search("javascript");
// Create resolver with boolean operations
const resolver = new Resolver()
.and(titleResults, contentResults) // Must match in both title AND content
.or(tagResults); // OR match in tags
const finalResults = resolver.resolve();
console.log(finalResults); // [1, 3] - documents matching the complex queryApply result manipulation operations like limiting, offsetting, and boosting.
/**
* Limit the number of results returned
* @param limit - Maximum number of results to return
* @returns Resolver instance for chaining
*/
limit(limit: number): Resolver<D, W, S>;
/**
* Set offset for result pagination
* @param offset - Number of results to skip
* @returns Resolver instance for chaining
*/
offset(offset: number): Resolver<D, W, S>;
/**
* Apply boosting to search results
* @param boost - Boost factor for result scoring
* @returns Resolver instance for chaining
*/
boost(boost: number): Resolver<D, W, S>;Usage Examples:
// Complex query with result processing
const resolver = new Resolver()
.and(titleResults, contentResults)
.not(excludedResults)
.boost(1.5) // Boost relevance scores
.limit(10) // Return max 10 results
.offset(0); // Start from first result
const results = resolver.resolve();Finalize and resolve the query results with optional configuration.
/**
* Resolve final results from the query operations
* @param options - Resolution configuration options
* @returns Final resolved results with proper typing
*/
resolve<
h extends HighlightOptions | boolean = H,
e extends boolean = h extends HighlightOptions ? true : E,
a extends boolean = A
>(options?: DefaultResolve<D, h, true, e>):
DocumentSearchResultsWrapper<D, W, S, h, true, true, e, false, a>;Usage Examples:
// Basic resolution
const basicResults = resolver.resolve();
// Resolution with options
const detailedResults = resolver.resolve({
includeScores: true,
sortBy: "relevance",
format: "detailed"
});Complex query combinations using multiple boolean operations and intermediate resolvers.
Usage Examples:
// Complex multi-field search with boolean logic
const searchTerm = "javascript";
const excludeTerm = "deprecated";
// Search multiple fields
const titleResults = titleIndex.search(searchTerm);
const contentResults = contentIndex.search(searchTerm);
const authorResults = authorIndex.search("expert");
const excludeResults = contentIndex.search(excludeTerm);
// Build complex query: (title OR content) AND author AND NOT deprecated
const complexResolver = new Resolver()
.or(titleResults, contentResults) // Match in title OR content
.and(authorResults) // AND written by expert authors
.not(excludeResults); // BUT NOT deprecated content
const finalResults = complexResolver
.boost(1.2)
.limit(20)
.resolve();
console.log("Complex search results:", finalResults);Use resolvers within other resolvers for highly complex query structures.
Usage Examples:
// Create sub-queries
const techResolver = new Resolver()
.or(
titleIndex.search("javascript"),
titleIndex.search("python"),
titleIndex.search("java")
);
const levelResolver = new Resolver()
.or(
contentIndex.search("beginner"),
contentIndex.search("intermediate")
);
const typeResolver = new Resolver()
.and(
tagIndex.search("tutorial"),
tagIndex.search("guide")
);
// Combine sub-queries
const masterResolver = new Resolver()
.and(techResolver.resolve()) // Must match tech terms
.and(levelResolver.resolve()) // AND match difficulty level
.or(typeResolver.resolve()) // OR match content type
.not(contentIndex.search("deprecated"));
const results = masterResolver
.boost(1.5)
.limit(15)
.resolve();Build queries dynamically based on conditions and user preferences.
Usage Examples:
function buildSearchQuery(params) {
const resolver = new Resolver();
// Base search across multiple fields
if (params.query) {
const titleResults = titleIndex.search(params.query);
const contentResults = contentIndex.search(params.query);
resolver.or(titleResults, contentResults);
}
// Add category filter if specified
if (params.category) {
const categoryResults = categoryIndex.search(params.category);
resolver.and(categoryResults);
}
// Add author filter if specified
if (params.author) {
const authorResults = authorIndex.search(params.author);
resolver.and(authorResults);
}
// Exclude certain content types
if (params.excludeTypes && params.excludeTypes.length > 0) {
params.excludeTypes.forEach(type => {
const excludeResults = typeIndex.search(type);
resolver.not(excludeResults);
});
}
// Apply pagination and boosting
return resolver
.boost(params.boost || 1.0)
.limit(params.limit || 20)
.offset(params.offset || 0)
.resolve();
}
// Use dynamic query builder
const searchResults = buildSearchQuery({
query: "web development",
category: "programming",
excludeTypes: ["archived", "draft"],
boost: 1.3,
limit: 10
});Custom scoring algorithms and result ranking with the Resolver.
Usage Examples:
// Multiple search criteria with different weights
const primaryResults = titleIndex.search("important topic");
const secondaryResults = contentIndex.search("important topic");
const tertiaryResults = tagIndex.search("important");
// Weight different result sources
const weightedResolver = new Resolver()
.or(
new Resolver(primaryResults).boost(3.0).resolve(), // High weight for title matches
new Resolver(secondaryResults).boost(1.5).resolve(), // Medium weight for content matches
new Resolver(tertiaryResults).boost(0.8).resolve() // Lower weight for tag matches
);
const rankedResults = weightedResolver
.limit(25)
.resolve({
sortBy: "score",
includeScores: true
});interface ResolverOptions {
/** Initial search results to process */
results?: IntermediateSearchResults;
/** Default boost factor */
defaultBoost?: number;
/** Result processing mode */
mode?: "intersection" | "union" | "difference";
/** Custom scoring function */
scorer?: (results: any[], query: string) => number[];
/** Result deduplication strategy */
dedupe?: boolean | "strict" | "loose";
}interface ResolveOptions {
/** Include relevance scores in results */
includeScores?: boolean;
/** Result sorting strategy */
sortBy?: "relevance" | "score" | "id" | "custom";
/** Custom sorting function */
customSort?: (a: any, b: any) => number;
/** Result format configuration */
format?: "simple" | "detailed" | "custom";
/** Result post-processing function */
postProcess?: (results: any[]) => any[];
/** Include query metadata */
includeMetadata?: boolean;
}// Custom resolver with advanced options
const advancedResolver = new Resolver({
defaultBoost: 1.2,
mode: "intersection",
dedupe: "strict",
scorer: (results, query) => {
// Custom scoring algorithm
return results.map((result, index) => {
const baseScore = 1.0;
const positionPenalty = index * 0.1;
const lengthBonus = Math.min(query.length / 10, 0.5);
return baseScore - positionPenalty + lengthBonus;
});
}
});
// Resolution with detailed options
const detailedResults = advancedResolver.resolve({
includeScores: true,
sortBy: "custom",
customSort: (a, b) => {
// Custom sorting: primary by score, secondary by ID
if (a.score !== b.score) {
return b.score - a.score; // Descending by score
}
return a.id - b.id; // Ascending by ID
},
format: "detailed",
postProcess: (results) => {
// Add additional metadata to results
return results.map(result => ({
...result,
timestamp: Date.now(),
searchVersion: "1.0"
}));
},
includeMetadata: true
});type IntermediateSearchResults = Array<Id[]>;
interface ResolvedResult {
id: Id;
score?: number;
metadata?: {
query?: string;
timestamp?: number;
sources?: string[];
};
}
interface DetailedResult extends ResolvedResult {
boost: number;
originalScore: number;
finalScore: number;
rank: number;
}
type BooleanOperation = "and" | "or" | "xor" | "not";
type SortingStrategy = "relevance" | "score" | "id" | "custom";
type ResultFormat = "simple" | "detailed" | "custom";