2016-08-30 86 views
0

我想插入我的查询对象在pymongo连接器创建大熊猫数据帧:格式MongoDB的查询中使用Pymongo

import pandas as pd 
from pymongo import MongoClient 


def _connect_mongo(host, port, username, password, db): 

    if username and password: 
     mongo_uri = 'mongodb://%s:%[email protected]%s:%s/%s' % (username, password, host, port, db) 
     conn = MongoClient(mongo_uri) 
    else: 
     conn = MongoClient(host, port) 


    return conn[db] 


def read_mongo(db, collection, query={}, host='localhost', port=27017, username=None, password=None, no_id=True): 
    """ Read from Mongo and Store into DataFrame """ 

    # Connect to MongoDB 
    db = _connect_mongo(host=host, port=port, username=username, password=password, db=db) 

    # Make a query to the specific DB and Collection 
    cursor = db[collection].find(query) 
    # Expand the cursor and construct the DataFrame 
    df = pd.DataFrame(list(cursor)) 

    # Delete the _id 
    # if no_id: 
    # del df['_id'] 

    return df 

我的查询被定义为:

query_1 = "{ 
        "status" : {"$ne" : "deprecated"}, 
        "geoLocationData.date" : { $gte : new ISODate("2016-08-03") } 
       }, 
        { "geoLocationData.date": 1, 
         "geoLocationData.iso": 1, 
         "httpRequestData.ipAddress": 1, 
         "geoLocationData.city": 1, 
         "geoLocationData.latitude": 1, 
         "geoLocationData.longitude": 1 }" 

将其插入 - 获得一个数据帧大熊猫:

df = read_mongo(db, collection, query_1, host, port, username, password) 

我得到的错误:

TypeError: filter must be an instance of dict, bson.son.SON, or other type that inherits from collections.Mapping 

如果我只是省略子文档,查询工作得很好,我可以将其转换为数据框。

我想这是关于将我的查询转换成字典(与子文件)。 我该怎么做?

+0

你是否按照'query_1 =“db.finger ......})”'的含义给查询提供了一个字符串? –

+0

对不起,我编辑过。我正在定义查询省略查找语句@SteveRossiter – xxxvinxxx

回答

0

您的query_1变量是一个字符串,它似乎包含两个字典。方法find首先将字典作为过滤器参数,然后将投影作为第二个参数。你只是传递一个论点。

这应该工作:

def read_mongo(db, collection, filter={}, projection={}, host='localhost', port=27017, username=None, password=None, no_id=True): 
    """ Read from Mongo and Store into DataFrame """ 

    # Connect to MongoDB 
    db = _connect_mongo(host=host, port=port, username=username, password=password, db=db) 

    # Make a query to the specific DB and Collection 
    cursor = db[collection].find(filter, projection) 
    # Expand the cursor and construct the DataFrame 
    df = pd.DataFrame(list(cursor)) 

    # Delete the _id 
    # if no_id: 
    # del df['_id'] 

    return df 

query_filter = { 
        "status" : {"$ne" : "deprecated"}, 
        "geoLocationData.date" : { $gte : new ISODate("2016-08-03") } 
       } 
query_project = { "geoLocationData.date": 1, 
         "geoLocationData.iso": 1, 
         "httpRequestData.ipAddress": 1, 
         "geoLocationData.city": 1, 
         "geoLocationData.latitude": 1, 
         "geoLocationData.longitude": 1 } 

df = read_mongo(db, collection, query_filter, query_project, host, port, username, password) 

不过,我不认为这种方法可以联合你想要它做的相当的。这是因为find操作中的投影只能包含或排除它不以您想要的方式映射它们的字段。你可以遍历你的游标来处理数据,然后传入构造函数DataFrame(注意不要创建巨大的python列表)。更好的方法是不使用find在所有,但使用aggregate

cursor = db[collection].aggregate([filter, projection]) 

现在你可以让你的过滤器match流水线阶段和投影一个project阶段。

query_project = { "geoDate":"$geoLocationData.date", 
        "geoLoc":"$geoLocationData.iso", 
        "ipAddress": "$httpRequestData.ipAddress", 
        "city": "$geoLocationData.city", 
         "lat": "$geoLocationData.latitude", 
         "long":"$geoLocationData.longitude"} 

df = read_mongo(db, collection, {"$match" : query_filter}, {"$project" : query_project}, host, port, username, password) 
+0

它的工作原理和加载数据。现在我有代表嵌入式文档(即geoLocationData和httpRequestsData)的每一列都是这种格式: '{u'city':u'Vantaa', u'date':datetime.datetime(2016,8,29, 10,59,23,361000), u'iso':u'FI', u'latitude':u'60.3131', u'longitude':u'24.9507'}'。 我如何解析它展开它们在不同的列? @SteveRossiter – xxxvinxxx

+0

我已经更新了我的答案,以反映我认为你正在尝试做的事情。您应该尝试理解聚合框架,因为它是查询mongodb最有效和最强大的方法。 –

+0

当我运行它提供的代码: 'df = read_mongo(db,collection,{$ match:query_filter},{$ project:query_project},host,port,username,password) ^ SyntaxError:invalid syntax' ' 如果我尝试把比赛中的报价为: ' “{$比赛:query_filter}”, “{$项目:query_project}”' 我得到: '类型错误:总()恰恰2个参数(给出3个)' @SteveRossiter – xxxvinxxx