/** * Batch utility functions for handling large product ID arrays in Solr queries * Prevents URL length limit errors when querying with >100 product IDs */ /** * Split an array into chunks of specified size * @param {Array} array - Array to split * @param {number} size - Chunk size (default: 100) * @returns {Array} Array of chunks */ export const chunkArray = (array, size = 100) => { if (!Array.isArray(array) || array.length === 0) return []; const chunks = []; for (let i = 0; i < array.length; i += size) { chunks.push(array.slice(i, i + size)); } return chunks; }; /** * Build a product ID OR clause for Solr query * @param {Array} ids - Array of product IDs * @returns {string} Formatted OR clause: "product_id_i:123 OR product_id_i:456..." */ export const buildProductIdOrClause = (ids) => { if (!Array.isArray(ids) || ids.length === 0) { return '*:*'; } return ids.map((id) => `product_id_i:${id}`).join(' OR '); }; /** * Validate query size to prevent exceeding HTTP limits * @param {string} query - Query string to validate * @param {number} maxSize - Maximum allowed size in characters (default: 6000) * @returns {Object} { valid: boolean, message: string, size: number } */ export const validateQuerySize = (query, maxSize = 6000) => { const size = query.length; return { valid: size <= maxSize, message: size > maxSize ? `Query size ${size} exceeds limit of ${maxSize}` : `Query size ${size} is within limit`, size, }; }; /** * Build batched Solr query parameters for large ID arrays * Chunks IDs into groups and creates separate OR clauses * @param {Array} ids - Product IDs to query * @param {number} chunkSize - How many IDs per chunk (default: 100) * @returns {Array} Array of OR clauses, one per chunk */ export const buildBatchedOrClauses = (ids, chunkSize = 100) => { if (!Array.isArray(ids) || ids.length === 0) { return ['*:*']; } const chunks = chunkArray(ids, chunkSize); if (chunks.length === 1) { // Single chunk, return standard OR clause return [buildProductIdOrClause(ids)]; } // Multiple chunks: return OR clauses wrapped with parentheses for combining return chunks.map((chunk) => `(${buildProductIdOrClause(chunk)})`); }; /** * Combine multiple OR clauses into a single query (for Solr) * @param {Array} orClauses - Array of OR clauses * @returns {string} Combined query with OR between clauses */ export const combineOrClauses = (orClauses) => { if (!Array.isArray(orClauses) || orClauses.length === 0) { return '*:*'; } if (orClauses.length === 1) { return orClauses[0]; } return orClauses.join(' OR '); }; /** * Merge Solr response documents from multiple queries * Removes duplicates based on product_id_i * @param {Array} responseArrays - Array of response.docs arrays * @returns {Array} Merged and deduplicated docs */ export const mergeSolrResults = (responseArrays) => { const seen = new Set(); const merged = []; responseArrays.forEach((docs) => { if (Array.isArray(docs)) { docs.forEach((doc) => { const id = doc.product_id_i; if (id && !seen.has(id)) { seen.add(id); merged.push(doc); } }); } }); return merged; };