Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/powershell/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 按小时聚合时返回日期对象_Python_Mongodb_Mongodb Query_Aggregation Framework_Mongoengine - Fatal编程技术网

Python 按小时聚合时返回日期对象

Python 按小时聚合时返回日期对象,python,mongodb,mongodb-query,aggregation-framework,mongoengine,Python,Mongodb,Mongodb Query,Aggregation Framework,Mongoengine,我正试图通过将datetime缩短为小时来聚合记录。是否有办法在mongoengine中执行此操作并保存字段类型 我的数据是: {'spent': 7, 'time_started': datetime.datetime(2015, 4, 21, 16, 2, 16, 661000)} {'spent': 3, 'time_started': datetime.datetime(2015, 4, 21, 17, 8, 5, 415000)} {'spent': 3, 'time_started'

我正试图通过将datetime缩短为小时来聚合记录。是否有办法在mongoengine中执行此操作并保存字段类型

我的数据是:

{'spent': 7, 'time_started': datetime.datetime(2015, 4, 21, 16, 2, 16, 661000)}
{'spent': 3, 'time_started': datetime.datetime(2015, 4, 21, 17, 8, 5, 415000)}
{'spent': 3, 'time_started': datetime.datetime(2015, 4, 21, 15, 52, 45, 917000)}
{'spent': 1, 'time_started': datetime.datetime(2015, 4, 21, 16, 42, 32, 313000)}
{'spent': 8, 'time_started': datetime.datetime(2015, 4, 21, 16, 35, 46, 863000)}
{'spent': 5, 'time_started': datetime.datetime(2015, 4, 21, 15, 55, 1, 217000)}
{'spent': 10, 'time_started': datetime.datetime(2015, 4, 20, 17, 41, 50, 5000)}
以下是我到目前为止得出的结论:

pipeline =[
    'match': {
        "time_started": {
            "$gte": datetime.datetime(2015, 4, 21, 0, 0, 0),
            }
        },
    'project': {
        "spent": "$spent",
         "time_started": {"$dateToString": {
                "format": "%Y-%m-%dT%H:00:00",
                "date": "$time_started"
            }}
        },
    'group': {
        "_id": {
            "time_started": "$time_started",
            },
        "spent_total": {"$sum": "$spent"}
        }
    ]
它工作得很好,但是结果中的“time_start”是一个字符串,而我需要datetime,如下所示:

{'spent_total': 16, 'time_started': datetime.datetime(2015, 4, 21, 16, 0, 0)}
{'spent_total': 3, 'time_started': datetime.datetime(2015, 4, 21, 17, 0, 0)}
{'spent_total': 8, 'time_started': datetime.datetime(2015, 4, 21, 15, 0, 0)}
对。您可以改为对对象使用“日期数学”,然后它们将保留为BSON日期类型,并转换为驱动程序中的本机类型:

pipeline = [
    { '$match': {
        "time_started": {
            "$gte": datetime.datetime(2015, 4, 21, 0, 0, 0),
            }
        }
     }},
     { "$group": {
        "_id": {
             "$add": [
                 { "$subtract": [
                     { "$subtract": [
                         "$time_started", datetime.datetime(1970, 1, 1) 
                     ]},
                     { "$mod": [
                         { "$subtract": [
                             "$time_started", datetime.datetime(1970, 1, 1) 
                         ]},
                         1000 * 60 * 60
                     ]}
                 ]},
                 datetime.datetime(1970, 1, 1)
             ]
        },
        "spent_total": { "$sum": "$spent" }
     }}
 ];

Class._get_collection().aggregate(pipeline);
其中的基本概念是,当您从日期字段的值中减去“历元日期”时,返回的值是数字。在这里,您应用一个模(
$mod
),计算出一小时内毫秒数的余数,并将日期四舍五入到小时

如果将“历元日期”添加到数字中,则相反,然后返回一个新的
date
对象,该对象等于以毫秒为单位表示的值


因为它已经是一个日期了,所以驱动程序会相应地处理它,不需要翻译。比使用字符串或其他运算符要好得多。另外请注意,您不需要
$项目
,只需将这种转换直接应用到
$组
中的
\u id
,甚至可以加快速度。

谢谢,这很有效!远非显而易见,但确实很有创意!))@funkifunki让我们称之为一个未记录的“特性”。但这就是“数学”与日期对象在aggregation管道中的行为方式。现在你知道了。