在map_reduce操作期间通过日期比较进行MongoEngine / PyMongo过滤失败

时间:2012-08-08 14:52:59

标签: python mongodb mapreduce pymongo mongoengine

我已经构建了一些收集大量信息的程序,并将它们以原始形式存储在Mongo数据库中。稍后,在预先指定的时间段,调用map_reduce个操作来评估此信息的子集。

必须保留原始数据,不能将其丢弃,但map_reduce操作不一定需要整个原始数据的结果才能运行。相反,我已经构建了map_reduce操作,使得它们可以仅在最新收集的数据上运行,而这些数据尚未被评估。稍后调用第二个map_reduce操作来处理精炼原始数据的减少。

我有必要指定一个查询过滤器,使得已经减少一次的原始数据在每个map_reduce操作中不减少a。我遇到的解决方案是指定一个过滤器(或通过map_reduce操作查询),它将仅选择 date_collected 字段的条目。预定日期。

首先,我尝试使用以下代码:

for k in SomeData.objects.filter(date_collected__gt=BULK_REQUEST_DATE).map_reduce(map_f, reduce_f, {'merge':'COLLECTION'}):
    print k.value

我还尝试了一个不到过滤器(只是为了确保我没有考虑日期倒退)。它也没有用。

现在这里有趣的是。如果我要删除map_reduce链式方法调用,并从上面打印k,如:

for k in SomeData.objects.filter(date_collected__gt=BULK_REQUEST_DATE):
    print k

过滤器工作正常,只选择在特定时间点之后收集的数据。

接下来,我攻击了MongoEngine queryset.py模块,并在map_reduce方法中添加了一个可选参数,以便可以将查询传递给map_reduce函数,如:

q = {'date_collected' : {'$lte' : BULK_REQUEST_DATE}}

for k in SomeData.objects.filter(date_collected__lte=BULK_REQUEST_DATE).map_reduce(map_f, reduce_f, {'merge':'COLLECTION'}, query=q):
        print k.value

同样,这未能产生预期的结果。然而,没有错误。通过传递配置不正确的查询,或者将高级查询运算符map_reduce更改为$lte之类的内容,我能够打破 $asdfjla操作,所以我知道无论我通过map_reduce方法传递的任何查询都在进行评估,至少不会造成任何问题。

在所有上述执行map_reduce操作的方法中,评估了原始存储器中的所有数据的全部内容。我没有尝试打破map_reduce操作,但他们也未能将查询限制为数据的子集。

有人能指出我的逻辑中存在比较日期的缺陷吗?

日期作为python datetime.time存储在mongo数据库中。在比较两个日期之前,我还尝试将日期更改为ISO格式。这在python或javascript方面不起作用。

任何帮助将不胜感激!谢谢。

更新

我已经确定问题不在于MongoEngine。

问题与使用" $ gte"等运算符在javascript中比较PyMongo Datetime对象的方式有关。或" $ lte"。由于某种原因,datetime对象不会被视为这样,或者没有正确转换为javascripts日期。

我还没有找到比这更多的东西,但如果你有任何指针,我肯定可以使用它们!

更新

我已经从测试MongoEngine转向直接测试PyMongo。以下代码无法生成预期结果。注意:epochtime是一个字段,包含自创建文档的纪元以来的秒数(在int中)。 Timestamp也是一个int,在运行时创建。

j = db.data.map_reduce(map_f, reduce_f, {'merge':'COLLECTION'}, query={'epochtime':{'$lte':timestamp}})
for x in j.find():
    print x

我希望当" $ lte"如果使用,则for循环将打印x,因为时间戳>永恒的时代。或者,我希望如果" $ gte"如果使用,将不会打印任何值。相反,在两个事件中都打印相同的值; " $ lte"没有区别。或" $ gte"使用运算符。

我错过了什么?

更新

我应用了与之前更新相同的操作,期望自从纪元以来的秒数,我将集合中的每个epochtime字段重置为从1开始的递增数字。我还设置timestamp = 1。然后我执行了map_reduce操作。它工作正常。

这让我觉得字段的字节大小存在问题?我使用浮点字段复制了上述结果。它适用于小浮点数,但不适用于表示自纪元以来秒数(带小数)的浮点数。

我绝对错过了一些基本的东西......

更新

找到可能导致问题的内容。当我对map_reduce使用合并输出函数时,它会根据查询成功过滤,然后第一次将缩减数据保存到指定的集合中。但是,这仅适用一次。后,如果有的话,查询中的条件无法一致地工作。这似乎只发生在合并输出函数中。使用replace,reduce或inline输出方法时不会发生这种情况。此外,似乎当在同一个集合上第二次使用合并函数时,查询参数中的条件取决于要比较的两个值的大小 - 请参阅先前的更新。

我不知道这意味着什么,或者为什么会这样。

0 个答案:

没有答案