无法过滤嵌套数组中的日期以匹配查询Mongodb

时间:2019-01-22 08:55:26

标签: node.js mongodb mongoose

我已经为FreecodeCamp构建了以下项目。 我的项目必须保存用户名和练习以及参加比赛的时间(包括日期)。 我的问题是访问日期的集合数据数组,仅返回日期并在url中执行匹配查询。 这是我返回的JSON代码。我只需要设置一个限制日期,并执行与用户在url中的查询所设置的查询相匹配的查询,以返回与2018-11-22T00:00:00.000Z匹配的日期数量(例如localhost:3000/addme16?id=5_OYzu1QG&start=22 November 2018&end=22 November 2018&limit=2)。因此,如果将查询限制设置为两个日期并返回练习,则仅返回两个与2018-11-22T00:00:00.000Z匹配的日期对象。

{
    "_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
}

我忘记添加架构和将查询字符串日期更改为iso对象日期的方法。这是我的额外代码信息,这些信息显示了如何向用户数据添加练习。我只想返回与数据库中ISO数据查询日期匹配的日期

//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 个答案:

答案 0 :(得分:0)

给出网址字符串: 2018-11-22T00:00:00.000Z (example localhost:3000/addme16?id=5_OYzu1QG&start=22 November 2018&end=22 November 2018&limit=2)

然后提取年,月和日:

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

使用$gte(大于等于)和$lt(小于第二天)可确保获得当天的所有时间戳记

答案 1 :(得分:0)

我终于找到了一种设置匹配日期或文档日期限制的方法。我包含以下代码。

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"})
	  }
	})
	  }
	 })
})

这最终返回了project的必需参数,这对于完成我的Free Code Camp项目是必需的。使用以下链接[如何使用猫鼬查询集合数组中的数据

how to query data inside an array of the collection using mongoose stackoverflow如何在使用猫鼬收集数组的内部查询数据