summaryrefslogtreecommitdiff
path: root/src/lib/utils
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/utils')
-rw-r--r--src/lib/utils/batchSolrQueries.js113
1 files changed, 113 insertions, 0 deletions
diff --git a/src/lib/utils/batchSolrQueries.js b/src/lib/utils/batchSolrQueries.js
new file mode 100644
index 00000000..486f1778
--- /dev/null
+++ b/src/lib/utils/batchSolrQueries.js
@@ -0,0 +1,113 @@
+/**
+ * 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>} 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<string|number>} 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<string|number>} ids - Product IDs to query
+ * @param {number} chunkSize - How many IDs per chunk (default: 100)
+ * @returns {Array<string>} 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<string>} 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<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;
+};