2

我正在寻找一种方法来查询 mongo 以获取与变量相比匹配两个字段之间结果的文档。

例如,重叠的日期范围。我有一个具有以下架构的文档:

{startDate : someDate, endDate : otherDate, restrictions : {daysBefore : 5, daysAfter : 5}}

我的用户将提供他们自己的日期范围,例如

var userInfo = { from : Date,  to : Date}

我需要满足这个条件的文件:

startDate - restrictions.daysBefore <= userInfo.to && endDate + restrictions.daysAfter >= userInfo.from;

我尝试使用$where子句,但我失去了 and 的上下文,to因为from它们是在 where 函数的范围之外定义的。

我想这样做而不拉下所有结果,或者在插入时创建另一个字段。

有没有一种简单的方法可以完成这个查询?

4

1 回答 1

2

聚合框架 [AF] 会做你想做的事。AF 后端是用 C++ 编写的,因此比使用 JavaScript 作为额外的好处要快得多。除了比 JavaScript 更快之外,还有很多我们不鼓励使用 $where 的原因,其中一些可以在 $where 文档中找到。AF 文档(即使用的好东西): http ://docs.mongodb.org/manual/reference/aggregation/ 我不确定您存储的数据的格式,这也会影响性能。例如,如果日期是自 1970 年 1 月 1 日(unix 纪元)以来的标准毫秒日期,并且 daysBefore 存储在(每天的毫秒数)*(天数)中,您可以像下面的示例一样使用简单的数学运算。这是非常快的。如果没有,AF 中有可用的日期转换,但是除了获得差异之外,进行转换当然更昂贵。

在 Python 中(您的个人资料提到了 Django)datetime.timedelta 可用于 daysBefore。例如 5 天:import datetime daysBefore=datetime.timedelta(5)

有两种主要方法可以处理您想要在 AF 中使用的内容。直接进行计算并匹配它,或者创建一个新列并与之匹配。对于复杂或大规模的部署,您的特定用例和测试将是必要的。来自 shell 的聚合命令,用于匹配 Python 中的计算:

fromDate=<program provided>
db.collection.aggregate([{"$match":{"startDate":{ "$lt": {"$add": ["$restrictions.daysBefore", fromDate]}}}}])

如果您想在同一个 $match 中运行多个计算,请使用 $and:[{}, {}, ..., {}]。为了清楚起见,我省略了这一点。AF 的更多聚合文档可在以下位置找到: http ://api.mongodb.org/python/current/examples/aggregation.html#aggregation-framework

请注意,“聚合”还包括 Mongo 中的 map reduce,但在这种情况下,AF 应该能够完成所有操作(而且速度更快)。

如果您需要有关 AF 的任何进一步信息,或者如果文档有任何不清楚的地方,请随时询问。

最好的,查理

于 2013-09-18T16:09:32.070 回答