简体   繁体   English

pymongo在聚合查询中包含javascript

[英]pymongo include javascript in aggregate query

I'm currently tasked with researching databases and am trying various queries using the pymongo library to investigate suitability for given projects. 我目前负责研究数据库,并正在尝试使用pymongo库进行各种查询,以调查给定项目的适用性。

My timestamps are saved in millisecond integer format and I'd like to do a simple sales by day aggregated query. 我的时间戳以毫秒整数格式保存,我想按日汇总查询进行简单的销售。 I understand from here (answer by Alexandre Russel) that as the timestamps weren't uploaded in BSON format I can't use date and time functions to create bins, but can manipulate timestamps using embedded javascript. 我从这里了解到(由于Alexandre Russel的回答) ,因为时间戳不是以BSON格式上载的,所以我不能使用日期和时间函数来创建bin,但是可以使用嵌入式javascript处理时间戳。

As such I've written the following query: 因此,我编写了以下查询:

 [{
    "$project": {
        "year": {
            "$year": {
                "$add": ["new Date(0)", "$data.horaContacto"]
            }
        },
        "month": {
            "$month": {
                "$add": ["new Date(0)", "$data.horaContacto"]
            }
        }
    }
}, {
    "$group": {
        "_id": {
            "year": "$year",
            "month": "$month"
        },
        "sales": {
            "$sum": {
                "$cond": ["$data.estadoVenta", 1, 0]
            }
        }
    }
}]

But get this error: 但是得到这个错误:

pymongo.errors.OperationFailure: exception: $add only supports numeric or date types, not String

I think whats happening is that the js "new Date(0)" is being interpreted by the mongo driver as a string, not applied as js. 我认为发生的事情是mongo驱动程序将js "new Date(0)"解释为字符串,而不是作为js应用。 If I remove the encapsulating inverted double quotes then Python tries to interpret this code and errors accordingly. 如果删除封装的双引号,Python会尝试解释此代码并相应地出错。 This is just one example and I'd like to include more js in queries in future tests but can't see a way to get it to play nicely with Python (having said this I'm fairly new to Python too). 这只是一个例子,我想在将来的测试中在查询中包含更多的js,但找不到让它与Python完美配合的方法(尽管我也对Python相当陌生)。

Does anybody know if: 有人知道吗:

  • I'm correct in assuming the error occurs because mongo interprets the JS as a string and tries to sum it directly? 我假设错误发生是正确的,因为mongo将JS解释为字符串并尝试直接求和?
  • If I can indicate to mongo this is JS from Python without Python trying to intepret the code? 如果我可以向mongo指示这是Python中的JS,而没有Python试图解释代码?

So far I've tried searching via Google and various combinations of single and double inverted commas. 到目前为止,我已经尝试通过Google以及单引号和双引号的各种组合进行搜索。

Pasted below is a few rows of randomly generated test data if required: 如果需要,请在下面粘贴几行随机生成的测试数据:

Thanks, 谢谢,

James 詹姆士

{'_id': 0,'data': {'edad': '74','estadoVenta': True,'visits': [{'visitLength': 1819.349246663518,'visitNo': 1,'visitTime': 1480244647948.0}],'apellido2': 'Aguilar','apellido1': 'Garcia','horaContacto': 1464869545373.0,'preNombre': 'Agustin','_id': 0,'telefono': 630331272,'location': {'province': 'Aragón','city': 'Zaragoza','type': 'Point','coordinates': [-0.900203, 41.747726],'country': 'Spain'}}}, 
{'_id': 1,'data': {'edad': '87','estadoVenta': False,'visits': [{'visitLength': 2413.9938072105024,'visitNo': 1,'visitTime': 1465417353597.0}],'apellido2': 'Torres','apellido1': 'Acosta','horaContacto': 1473404147769.0,'preNombre': 'Sara','_id': 1,'telefono': 665968746,'location': {'province': 'Galicia','city': 'Cualedro','type': 'Point','coordinates': [-7.659321, 41.925328],'country': 'Spain'}}}, 
{'_id': 2,'data': {'edad': '48','estadoVenta': True,'visits': [{'visitLength': 2413.9938072105024,'visitNo': 1,'visitTime': 1465415138597.0}],'apellido2': 'Perez','apellido1': 'Sanchez','horaContacto': 1473404923569.0,'preNombre': 'Sara','_id': 2,'telefono': 665967346,'location': {'province': 'Galicia','city': 'Barcelona','type': 'Point','coordinates': [-7.659321, 41.925328],'country': 'Spain'}}}

The MongoDB aggregation framework cannot use any Javascript. MongoDB聚合框架不能使用任何Javascript。 You must specify all the data in your aggregation pipeline using BSON. 您必须使用BSON在聚合管道中指定所有数据。 PyMongo can translate a standard Python datetime to BSON, and you can send it as part of the aggregation pipeline, like so: PyMongo可以将标准的Python日期时间转换为BSON,您可以将其作为聚合管道的一部分发送,如下所示:

import datetime

epoch = datetime.datetime.fromtimestamp(0)
pipeline = [{
    "$project": {
        "year": {
            "$year": {
                "$add": [epoch, "$data.horaContacto"]
            }
        },
        # the rest of your pipeline here ....
    }
}]

cursor = db.collection.aggregate(pipeline)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM