1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
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;
};
|