Is there any way of chaining queries dynamically?
For example, given the following GET request
/collection?field1=value1&field2=value2&sort=field3 asc
It is easy without the sort query
/collection?field1=value1&field2=value2
var query = {}
for (var key in query) {
query[key] = req.query[key]
}
Collection.find(query)
But how do I build the GET request if there are optional query keys such as sort, expand, and select which map to Collection.sort, Collection.populate, Collection.select respectively?
In other words, suppose you have a dynamic array of Query methods:
queries = [populate, select, sort]
Would the solution be the following:
var query = Collection.find()
for (var q in queries)
query = query.q
CodePudding user response:
You just iterate through the query parameters and separate out the ones that are operations versus actual query criteria. Using your examples:
// sample data for req.query
const req = {
query: {
sort: "field9",
field1: "someValue",
field2: "otherValue",
field3: "highValue"
}
};
const queries = new Map();
const operations = new Map([
["populate", false],
["sort", false],
["select", false]
]);
for (const [key, value] of Object.entries(req.query)) {
if (operations.has(key)) {
operations.set(key, value);
} else {
queries.set(key, value);
}
}
// here:
// queries contain the non-operation pairs
// operations (if not false) contain the operation value such
// as sort => "field9"
console.log("operations:");
for (let [key, value] of operations.entries()) {
console.log(`${key} => ${value}`);
}
console.log("queries:");
for (let [key, value] of queries.entries()) {
console.log(`${key} => ${value}`);
}
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
To run the operation, you'd then have to check which operations are present and branch your code and query based on which operations are present.