如果Mongo

时间:2016-02-15 20:37:38

标签: python mongodb mongodb-query pymongo aggregation-framework

我试图检查Mongo中两个日期之间是否存在任何日期(我正在使用pymongo)。

id_categoria    = 885
min_date        = parse("2015-11-01")
max_date        = parse("2015-11-20")
query_mongo     = {"categoryId" : id_categoria,"dataDate":{"$lte":max_date,"$gte":min_date}}

print colLastData.find(query_mongo,projection={'data':0}).count()

打印返回这两个日期之间的数据总数,例如,如果我在2015-11-01和2015-11-20之间只有10天,则打印将返回10.但我需要的是打印返回是的,因为我有10天没有数据。

2015-11-01至2015-11-10:使用数据!
2015-11-11至2015-11-20:没有数据!

我使用它但是同样的事情:

print colLastData.find(query_mongo,projection={'data':0}).count() > 0

如果范围在Mongo中只有一天,那么打印将返回True并且这是错误的,因为我想要的只是如果mongo在这些天之间有数据的话,只返回True!

更新1: 我觉得这个查询与OR一起使用。

query_mongo     = {"categoryId" : id_categoria,"dataDate":{"$lte":max_date,"$gte":min_date}}

因为显示"任何"这两个日期之间的数据,但我需要的是" AND"。如果有一天没有数据,则查询必须返回False。

2 个答案:

答案 0 :(得分:1)

听起来你只是想确保中间所有日子都有数据。我建议你做一些辅助功能:

from datetime import datetime
def is_complete(min_date, max_date):
    days = (datetime.strptime(max_date,"%Y-%d-%m")-datetime.strptime(min_date,"%Y-%d-%m")).days
    # do your query now
    min_date = parse(min_date)
    max_date = parse(max_date)
    #... rest of your query
    if colLastData.find(query_mongo,projection={'data':0}).count() == days:
        return colLastData, True
    else:
        return colLastData, False


is_complete("2015-11-01", "2015-11-20") # would return your query data in the first element and true or false in the second

答案 1 :(得分:1)

您想要的基本想法是确保返回的天数连续到该范围内的所有天数。这意味着“计算”结果范围内的数据中的“不同”天数等于日期之间的天数。

为此,您可以使用.aggregate()声明:

days = (datetime.strptime(max_date,"%Y-%d-%m")-datetime.strptime(max_date,"%Y-%d-%m")).days

colLastData.aggregate([
    { "$match": { 
        "categoryId" : id_categoria,
        "dataDate": { "$lte":max_date, "$gte":min_date }
    }},
    { "$group": {
        "_id": {
            "$subtract": [
                { "$subtract": [ "$dataDate", datetime.datetime.utcfromtimestamp(0) ] },
                { "$mod": [
                    { "$subtract": [ "$dataDate", datetime.datetime.utcfromtimestamp(0) ] },
                    1000 * 60 * 60 * 24
                ]}
            ]
        }
    }},
    { "$group": { 
        "_id": None,
        "count": { "$sum": 1 }
    }},
    { "$match": { "count": days } }
])

如果不同天数的计数等于输入日期之间的天数,则查询将仅返回结果。

MongoDB查询本身会遍历集合对象以进行相互比较。因此,标准查询无法确定源范围的数据结果中没有“缺失日期”。

但您可以使用.aggregate()等工具创建语句,以便在服务器上为您计算出逻辑。这基本上是将圆形日期值$group设置为开始日期,然后再次使用$group来计算这些出现次数。如果日期之间出现差异$match,那么所有日期都会出现。