我有一个MongoDB数据库,用于存储具有创建时间和时间戳的记录。我使用官方C#驱动程序连接并查询此数据库。
正常用例涉及获取所有> = startDateTime和< = endDateTime的记录,这非常简单。
但是,有时候数据点距离我需要在startDateTime和endDateTime插值的周期的开始和结束都足够远。为此,我显然需要startDateTime之前的最后一条记录,以及endDateTime之后的第一条记录。使用三个查询很容易做到这一点,但我想避免这样做以减少到数据库的往返次数。
是否可以通过单个查询实现此目的?
编辑:因为我被要求澄清用例:
假设我有一个每小时记录温度的传感器。温度和时间戳存储在MongoDB集合中。现在,我想绘制昨天的温度图,所以我要求所有时间戳大于> = 2014.02.04 00:00:00且时间戳< 2014.02.05 00:00:00
事实证明,这个传感器每小时记录55分钟,因此我的第一个数据点是昨天55分钟,而我的最后一个数据点是距离昨天结束的5分钟。
除了属于我的时间范围内的24个值之外,我想在2014.02.03 23:55:00和2014.02.05 00:55:00获取值,以便我可以进行插值。这需要概括为在我的期间开始之前获取最后一条记录以及在我的期间结束之后的第一条记录,因为我无法知道传感器记录的频率,记录的时间,或者是否已经脱机在任何时候。
Edit2:我今天的代码的缩写版本:
//Get last record before the period
var cursor = collection.Find(
Query.LT("DateTime", startDateTime)
);
cursor.Limit = 1;
cursor.SetSortOrder(SortBy.Descending("DateTime"));
//Not shown: getting the record from the cursor and adding it to the collection
//Getting all records that fall within the specified period
cursor = collection.Find(
Query.And(
Query.GTE("DateTime", startDateTime),
Query.LTE("DateTime", endDateTime))
);
//Not shown: getting the records from the cursor and adding them to the collection
//Get first record after the period
cursor = collection.Find(
Query.GT("DateTime", endDateTime)
);
cursor.Limit = 1;
cursor.SetSortOrder(SortBy.Ascending("DateTime"));
//Not shown: getting the record from the cursor and adding it to the collection
答案 0 :(得分:0)
如果您不知道传感器记录的频率,并且如果实际上有一个读数及时记录在“正好”24小时之外,那么最好的方法是做3个陈述。
删除两个约束中的一个可以在较少的语句中获得结果。
如果您担心3个请求“缓慢”,您应该努力使请求执行得更快,例如使用索引。
答案 1 :(得分:0)
您的方法似乎正在寻找三个查询操作中隐含的SQL UNION模拟。这种方法的操作很明确:
虽然这很清楚,但可能只是我,但我没有看到这种方法的实用性。根据你所写的内容,你似乎正在尝试为图表收集24点,并且该图表将遵循24小时的时间段。因此,它会发现发出的三个查询的组合结果将在最多26条记录和最差2条记录之间返回。或者甚至可能是一个,如果事先没有记录,并且取决于查询的运行时间。
鉴于此,有两条记录可以远远超出你的日间范围而且除了说在之前或之后的几小时或几天没有任何活动之外没有多大用处。< / p>
我知道这是一个无代码响应,但没有UNION模拟可以做你正在做的事情,但我可以提出,也许你不需要做你正在做的事情。
继续我所看到的以及看起来似乎是什么功能,我看不出简单地以小于1小时的结尾取出记录并且以降序排序顺序限制到最后26小时的错误。从那里你可以做出你想要的任何决定来代表什么数据,我们讨论的是非常少的结果。
如果你真的相信你必须拥有从你正在运行的查询中产生的一组结果,那么一定要运行三个查询。同样,这些是小结果集,时间应该可以忽略不计。