I'm not sure of an easier way to do this. But let me show my findings
interests: ['A', 'B', 'E']
now to capture your requirement the filters statement should be something like
'(interests:A AND interests:B) OR (interests:A AND interests:E) OR (interests:B AND interests:E)'
which if take as a boolean expression is in the form of AB+AC+BC.
But this particular query cannot be used with algolia according to their docs
For performance reasons, we do not support the following boolean combinations:
...
We limit filter expressions to a conjunction (ANDs) of disjunctions
(ORs). For example you can use filter1 AND (filter2 OR filter3)), but
not ORs of ANDs (e.g. filter1 OR (filter2 AND filter3).
But we can convert the AB+AC+BC to a product of sum format. I used https://www.dcode.fr/boolean-expressions-calculator and obtained the equivalent
(A+B).(A+C).(B+C) which would then be
'(interests:A OR interests:B) AND (interests:A OR interests:E) AND (interests:B OR interests:E)'
The query also depends on how many elements are there in the interests array. For example if interests: ['A', 'E', 'C', 'F'] your final filter query would look in the form
'(interests:A OR interests:E OR interests:C) AND (interests:A OR interests:E OR interests:F) AND (interests:A OR interests:C OR interests:F) AND (interests:E OR interests:C OR interests:F)'
Individual product terms have length of interest array-1 terms
TLDR: '(interests:A OR interests:B) AND (interests:A OR interests:E) AND (interests:B OR interests:E)'
you can use a use a combination generating code and get the filter query.
Here is a JS example based on this solution.
const k_combinations = (set, k) => {
let i, j, combs, head, tailcombs;
if (k > set.length || k <= 0) {
return [];
}
if (k == set.length) {
return [set];
}
if (k == 1) {
combs = [];
for (i = 0; i < set.length; i++) {
combs.push([set[i]]);
}
return combs;
}
combs = [];
for (i = 0; i < set.length - k + 1; i++) {
head = set.slice(i, i+1);
tailcombs = k_combinations(set.slice(i + 1), k - 1);
for (j = 0; j < tailcombs.length; j++) {
combs.push(head.concat(tailcombs[j]));
}
}
return combs;
}
const combinations = (set) => {
let k, i, combs, k_combs;
combs = [];
for (k = 1; k <= set.length; k++) {
k_combs = k_combinations(set, k);
for (i = 0; i < k_combs.length; i++) {
combs.push(k_combs[i]);
}
}
return combs;
}
const generateFilterQuery = (array) => {
const combinationSize = array.length - 1
const combinations = k_combinations(array, combinationSize)
return combinations.map((comb) => `(${comb.map(c => `interests:${c}`).join(" OR ")})`).join(" AND ")
}
console.log(generateFilterQuery(["A","B","E"]))
console.log(generateFilterQuery(["A","B","C","D"]))
console.log(generateFilterQuery(["A","B","C","D","E"]))
After generating the filter query pass it as the value of filters parameter
index.search('',{
filters: generatedQuery
}
).then(({hits}) => console.log(hits))