0
votes

I have build the following project for FreecodeCamp. My project has to save users name and exercise and time to compete(which includes a date). My problem is accessing the collective data array of dates and only returning dates and exercises matching query in url. Here is my JSON code returned. I need only a set limit dates and exercises matching query set by user's query in url to return amount of dates matching 2018-11-22T00:00:00.000Z (example localhost:3000/addme16?id=5_OYzu1QG&start=22 November 2018&end=22 November 2018&limit=2). Thus returning only two date objects matching 2018-11-22T00:00:00.000Z if query limit is set to two dates and exercises to be returned.

{
    "_id": "5_OYzu1QG",
    "username": "Timmy",
    "data": [{
            "description": "walking",
            "duration": 1,
            "date": "2018-11-22T00:00:00.000Z"
        },
        {
            "description": "Reading",
            "duration": 2,
            "date": "2019-01-01T00:00:00.000Z"
        },
        {
            "description": "Mountain Biking",
            "duration": 3,
            "date": "2019-01-22T00:00:00.000Z"
        }
    ],
    "__v": 0
}

I forgot to add my schema and my method of changing query string dates to iso object date. Here is my extra code information that show how i add a exercise to my users data. I only want to return the dates that match iso data query dates in database

//my schema
const mongoose = require('mongoose');
const Schema = mongoose.Schema;


const mySchema = new Schema ({
  _id:String,
  username: String,
  data: [{
	_id:false,  
    description : String,
    duration: Number,
    date :{type:Date}
  }]
});

const ExampleClass = mongoose.model('array',mySchema);

module.exports = ExampleClass;

//Save and create new user with id in array collection in mongodb
app.post('/api/exercise/new-user',(req, res)=>{
	  let myTest = req.body.user.myName;
	  let testing = /^[a-zA-Z\s]*$/
	  if(testing.test(myTest) === true && myTest !== ""){
		 
        array.find({username:req.body.user.myName})	
       .then(user => {
		if (user.length !== 0) {
			return res.send({error:"Name already exists in database"});
        } 
		if(user.length === 0){
			
			myId = shortid.generate();
			let data = new array({
				
		        username:req.body.user.myName,
				_id:myId,
	            })
				
			data.save(user,err=>{			
		if(err) throw err;
		return res.send({
			   username:req.body.user.myName,
		       _id:myId
	                });
	
	});
	
		}

    }).catch(err => {
 
         if(err) throw err;
  
    });
	  }else{
		res.send({username:"Invalid name! Please enter a string of letters for name."})  
	  }
	
});


//adding exercise to user data
app.post('/api/exercise/add',(req,res)=>{
	let myTest = req.body.user.userTask;
	const testing = /^[a-zA-Z\s]*$/
	const myNum =  /^\d+$/;
	const space = /^\s+$/;
	const checker = /^[0-9-]*$/
	let checking = req.body.user.userDuration;
	
	array.countDocuments({_id:req.body.user.userId},(err, count)=>{
	if(count>0){
		if(testing.test(myTest) === true && myTest !== ""){
			if(myNum.test(checking)=== true){
				let inPutDate;
		        let timestamp;
		        let d;
			 if(Object.keys(req.body.user.userDate).length === 0){
				 let date1 = Date.now();
		         date1 = new Date(date1);
                 date1.setUTCHours(0,0,0,0);
				array.findOneAndUpdate({_id:req.body.user.userId},{ $push :{data:{ description : req.body.user.userTask, duration :Number(req.body.user.userDuration),date:date1}}},{new:true}).then((data)=>{
				   date1 = new Date(date1).toDateString();
				   console.log(data)
				   res.send({ 
		           username:data.username,
		           date:date1,
		           description:req.body.user.userTask,
			       duration:Number(req.body.user.userDuration),
			       _id:req.body.user.userId
				   })
				}).catch(err => {
 
         if(err) throw err;
  
    });	
			 }else{
				 
				 timestamp = new Date(req.body.user.userDate);
				 d = moment(timestamp).format("YYYY-MM-DDT00:00:00.000") + "Z";
				 inPutDate = new Date(d);
				 let checking = d;
				 console.log(inPutDate)
				 console.log(typeof(inPutDate))
		  array.findOneAndUpdate({_id:req.body.user.userId},{ $push :{data:{ description : req.body.user.userTask, duration :Number(req.body.user.userDuration),date:inPutDate}}},{new:true}).then((data)=>{
				   inPutDate = new Date(inPutDate).toDateString();
				   console.log(data)
				   res.send({ 
		           username:data.username,
		           date:inPutDate,
		           description:req.body.user.userTask,
			       duration:Number(req.body.user.userDuration),
			       _id:req.body.user.userId
				   })
				}).catch(err => {
 
         if(err) throw err;
  
    });	
		  
		  
		  
			 }
				}else{
		res.send({duration:"Please type a number value"})
	}	
			}else{
		res.send({description:"Invalid description! Please enter a string of letters for description."})  
	  }
		}else{
			  res.send({_id:"Please type correct id from datbase"})
		  }
	}); 	
})

<!-- begin snippet: js hide: false console: true babel: false -->
2

2 Answers

0
votes

Given the url string: 2018-11-22T00:00:00.000Z (example localhost:3000/addme16?id=5_OYzu1QG&start=22 November 2018&end=22 November 2018&limit=2)

Extract the year, month and day then:

const data = db.Collection.find({
        date: {
            "created_on": {
                "$gte": new Date(2018, 11, 22),
                "$lt": new Date(2018, 11, 23)
            }
        }
    }).limit(2)

The use of $gte (greater than equal) and $lt (less than the next day) ensure you get all timestamps of that day

0
votes

I finally found a way to set a limit on matching date or dates of document. I am including following code.

app.get('/api/exercise/log',(req,res)=>{
 array.findById({_id:req.query.id},(err,data)=>{
		let iniate = new Date(req.query.start);
				 let one = moment(iniate).format("YYYY-MM-DDT00:00:00.000") + "Z";
				 let date1 = new Date(one);
				 console.log(date1);
				 console.log(typeof(date1));
	let iniate1 = new Date(req.query.end);
				 let two = moment(iniate1).format("YYYY-MM-DDT00:00:00.000") + "Z";
				 let date2 = new Date(two);
				 console.log(date2)
				 console.log(typeof(date2))	
  let myLength;
	   if(req.query.start === undefined && req.query.end === undefined && req.query.limit === undefined && req.query.id !== undefined){
		 myLength = data.data.length;
		array.aggregate([
    { $match: {_id: req.query.id}}]).then(data =>{
		res.send({count:myLength,data})
	})
	  }
	  else if(req.query.start !== undefined && req.query.end !== undefined && req.query.limit !== undefined && req.query.id !== undefined){
	  array.aggregate([
    { $match: {_id: req.query.id}},
    { $unwind: '$data'},{$match : {"$and" :  [{"data.date" :{$gte : date1} },
    {"data.date" :{"$lte" : date2}}]}}]).limit(Number(req.query.limit)).then(data =>{
		if(data.length >= Number(req.query.limit)){
		res.send(data)
		}else{
		return  res.send({error:"Document do not match limit requested"})
	  }
	})
	  }
	 })
})

This finally returned required parameters of project , which was needed to complete my project for Free Code Camp. Using following link[how to query data inside an array of the collection using mongoose

how to query data inside an array of the collection using mongoose stackoverflow how-to-query-data-inside-an-array-of-the-collection-using-mongoose