2013-09-09 3 views
4

Как я могу агрегировать результаты моего MongoDB по дате ObjectId. Пример:Совокупные результаты MongoDB по ObjectId date

По умолчанию результаты курсора:

cursor = [ 
    {'_id': ObjectId('5220b974a61ad0000746c0d0'),'content': 'Foo'}, 
    {'_id': ObjectId('521f541d4ce02a000752763a'),'content': 'Bar'}, 
    {'_id': ObjectId('521ef350d24a9b00077090a5'),'content': 'Baz'}, 
] 

Прогнозируемые результаты:

projected_cursor = [ 
    {'2013-09-08': 
     {'_id': ObjectId('5220b974a61ad0000746c0d0'),'content': 'Foo'}, 
     {'_id': ObjectId('521f541d4ce02a000752763a'),'content': 'Bar'} 
    }, 
    {'2013-09-07': 
     {'_id': ObjectId('521ef350d24a9b00077090a5'),'content': 'Baz'} 
    } 
] 

Это то, что я в настоящее время используют в PyMongo для достижения этих результатов, но это грязно, и я хотел бы чтобы узнать, как я могу это сделать, используя структуру агрегации MongoDB (или даже MapReduce):

cursor = db.find({}, limit=10).sort("_id", pymongo.DESCENDING) 
messages = [x for x in cursor] 
this_date = lambda x: x['_id'].generation_time.date() 
dates = set([this_date(message) for message in messages]) 
dates_dict = {date: [m for m in messages if this_date(m) == date] for date in dates} 

И да, я знаю, что самым простым способом было бы просто добавить новое поле даты в каждую запись, а затем заполнить его, но это не то, что я хочу сделать прямо сейчас.

Спасибо!

ответ

1

Так что это не отвечает на мой вопрос непосредственно, но я найти лучший способ, чтобы заменить все, что лямбда ерунду выше, с использованием языка Python setdefault:

d = {} 
for message in messages: 
    key = message['_id'].generation_time.date() 
    d.setdefault(key,[]).append(message) 

Благодаря @raymondh за подсказку в это PyCon разговор :

Transforming Code into Beautiful, Idiomatic Python

7

там нет никакого способа, чтобы сделать то, что вы просите с рамкой MongoDB в агрегации, потому что нет никакого оператора агрегации, что может превратить ObjectId во что-то датированное (есть JIRA ticket, хотя). Вы, однако, должны быть в состоянии выполнить все, что хотите, с помощью map-reduce:

+0

Спасибо. Я должен проверить производительность этого и делать это на Python, как в моем примере. Я никогда не знаю, должен ли я подталкивать такие вещи к БД или нет. –

+0

Кроме того, спасибо за билет ref, я также разместил эту тему. –