返回date范围内的数组文档

是否有可能连锁finById()select()find()在mongoose? 我正在尝试这样的事情,它不接受date,而只是返回在familyStats集合中的所有对象。

 module.exports.getFamilyStatsPast = function (req, res) { var id = req.params.id; var days = req.params.days; var pastDate = new Date(); pastDate.setDate(pastDate.getDate() - days).toISOString(); var currentDate = new Date().toISOString(); Worksets .findById(id) .select('familyStats') .find({ createdOn : { $gte: pastDate, $lte: currentDate } }) .exec(function (err, doc){ var response = { status: 200, message: [] }; if (err){ console.log("Error finding Workset"); response.status = 500; response.message = err; } else if(!doc){ console.log("Workset id not found in database", id); response.status = 404; response.message = {"message": "Workset Id not found."} } if(doc){ console.log("Found workset: ", doc); res .status(response.status) .json(doc) } else { res .status(response.status) .json(response.message); } }); }; 

我基本上是试图从Worksets集合中获取一个名为familyStats的数组,然后从那个数组中我只需要在上个星期到现在的pastDatecurrentDate之间创build的对象。

任何想法我做错了什么?

这是我的mongoose数据模式:

 var familyStatsSchema = new mongoose.Schema({ suspectFamilies: [{ name: String, size: String, sizeValue: Number, instances: Number, elementId: Number }], totalFamilies: Number, unusedFamilies: Number, oversizedFamilies: Number, inPlaceFamilies: Number, createdBy: String, createdOn: Date }); var healthCheckSchema = new mongoose.Schema({ onOpened: [worksetEventSchema], onSynched: [worksetEventSchema], itemCount : [worksetItemSchema], viewStats: [viewStatsSchema], linkStats: [linksStatsSchema], familyStats: [familyStatsSchema] }); mongoose.model('Worksets', healthCheckSchema); 

如果您只想从文档中的数组中获取特定date范围内的数据,则只需要从聚合框架中执行$filter操作:

 var id = req.params.id; var days = parseInt(req.params.days); var now = new Date(), firstDate = new Date(now.valueOf() - ( 1000 * 60 * 60 * 24 * days )); Worksets.aggregate([ { "$match": { "_id": ObjectId(id), "familyStats": { { "$elemMatch": { "createdOn": { "$gte": firstDate, "$lt": now } } } }}, { "$project": { "familtStats": { "$filter": { "input": "$familyStats", "as": "el", "cond": { "$and": [ { "$gte": [ "$$el.createdOn", firstDate ] }, { "$lt": [ "$$el.createdOn", now ] } ]} } } }} ],function(err, results) { // work with response }) 

有一个初始的$match条件,它和我们指定查询条件的.find()一样。 我将date范围条件添加到$elemMatch因为如果$elemMatch范围内没有date,那么根本没有返回文档的$elemMatch因为“范围expression式”实际上是应用于数组元素的AND条件。 没有它,你只是问全阵是否满足这些条件,而不是“如果他们之间有什么东西”

另外要注意的是ObjectId构造函数。 Mongoose通常从“string”中为“ _id字段“自动传播”值,但是对于聚合框架,它不能自行完成。 您需要手动执行“投射”。 因此,从Schema.Types导入并将其应用于此处接收的参数。

在文档(可能不包括_id约束)已经匹配之后, $projectstream水线阶段确定了返回结果的“形状”。 与标准查询投影一样,您必须在这里包含您实际需要的“所有”字段。 出于举例的目的,我只是返回有问题的数组。

$filter应用与$match相同的逻辑条件,除了这次它们实际应用于“数组元素本身” ,而不是“文档”是否符合条件。 任何不符合给定标准的数据将从返回的数组中移除。

除了所使用的操作符能够从服务器返回结果的“之前”数组的date范围外移除不需要的内容之外,这将为您提供与常规.find()查询大致相同的操作。

对于像您这样的大文档,这应该是您对其他arrays执行的常规操作。