I am a beginner in mongodb so would be great if someone advice me in how to write the below query efficiently.
I have a collection which has location and date as fields
There are 4 conditions for search
db.collection.find(query) --> Here this query object will change based on the request parameter.
query = {}query = {location query}query = {datequery}query = {location query , datequery}How i can make it simple with mongodb commands ? I know how to do it in SQL by adding whereclause based on the non null params in request but getting confused with nosql syntax.
You would build it like so:
const query = {};
if (req.params.location) {
query.location = req.params.location
}
if (req.params.date) {
query.date = new Date(req.params.date);
}
const results = await db.collection.find(query);
Where req.params is an object with location and date as optional fields.
You can build a query object.
const query = {};
req.params.location && (query.location = req.params.location)
req.params.date && (query.date = req.params.date)
The general problem you're facing here is the problem of building complex objects based on some parameters/inputs, which can be solved via a design pattern known as the builder pattern.
Though implementing such patterns can make your code look a bit complex (take this for example), here's my very simple implementation of it:
"use strict";
const queryBuilder = () => {
const query = {};
return {
addLocation: function(location){
if(typeof location === "string" && location.length>0){
query.location = location.trim();
}
return this;
},
addDate: function(date){
const dateObj = date ? new Date(date) : null;
if(dateObj && !isNaN(dateObj.valueOf())){
query.date = dateObj;
}
return this;
},
build: function(){
Object.freeze(query);
return query;
}
}
}
app.get('/:location/:date',async(req,res,next) => {
//however you're connecting to the db, you'll need a connected instance
const db = getDbSomehow();
const myQuery = queryBuilder()
.addLocation(req.params.location)
.addDate(req.params.date)
.build();
const results = await db.collection.find(myQuery).toArray();
//do whatever you need here
})
This looks like a lot more typing than some of the other answers that you've seen which must be working, but here are some advantages:
Object.freeze() or a library like deep-freeze in your build method to make the object immutable so that nothing can change it once it's done.