I am looking for a way to adapt query fields in the db-find selector. I need this because filters access different fields which may or may not be active all the time.
I have tried two options, but none of them work:
public getFilteredItems(filters: ItemFilter[]) {
let selectors: string[] = [];
filters.forEach((filter: ItemFilter) => {
selectors.push(
"\n{\n'" +
filter.field +
"': { $in: \n ['" +
filter.values.join("','") +
"']} \n} \n "
);
});
return this.getDB('items').find({
selector: {
$and: eval('selectors.join()'),
// $and: selectors.join(),
// $and: selectors,
},
});
}
2: In the second try I have tried to give a variable as query field, but the syntax does not allow it.
public getFilteredItems(filters: ItemFilter[]) {
return this.getDB('items').find({
selector: {
filters[0].field: { $in: filter.values }
},
});
}
Is there any other way?
EDIT: filters look like following:
filters: [
{
name: 'Filtergroup Template',
field: 'template',
values: ['case'],
always_active: true,
},
...
]
Error messages:
For option 1, $and: eval('selectors.join()'),
and $and: selectors.join(),
, I get the following error:
index.es.js?26cc:74 Uncaught (in promise) TypeError: selectors.forEach is not a function
at mergeAndedSelectors (index.es.js?26cc:74)
at massageSelector (index.es.js?26cc:242)
at find$1 (index-browser.es.js?5d16:1194)
at eval (index-browser.es.js?5d16:119)
at eval (index-browser.es.js?5d16:112)
at PouchDB.eval (index-browser.es.js?5d16:1380)
at eval (index-browser.es.js?a2df:138)
at new Promise (<anonymous>)
at PouchDB.eval (index-browser.es.js?a2df:125)
at PouchDB.eval [as find] (index.js?dd8f:14)
If I use $and: selectors,
, I will only get a note with {docs: Array(0), warning: 'no matching index found, create an index to optimize query time'}
Given the comments above, simply create a collection for an explicit $and
const filters = [{
name: 'Filter A',
field: 'lead guitar',
values: ['jerry']
},
{
name: 'Filter B',
field: 'rhythm guitar',
values: ['bobby']
}
];
const clauses = {};
filters.forEach(filter => clauses[filter.field] = {
$in: filter.values
});
const query = {
selector: {
$and: [clauses]
}
};
document.getElementById("content").innerText = JSON.stringify(query, undefined, 2);
<pre id="content"></pre>
DO note however that $and
is implicit which is covered here in the CouchDB docs.