5

MongoDB の結果を ObjectId の日付で集計するにはどうすればよいですか? 例:

デフォルトのカーソル結果:

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}

はい、最も簡単な方法は、新しい日付フィールドを各レコードに追加し、それによって集計することですが、それは今やりたいことではありません。

ありがとう!

4

3 に答える 3

7

更新:これを行う方法が組み込まれています。 https://stackoverflow.com/a/51766657/295687を参照してください。

ObjectId を日付のようなものに変換できる集計演算子がないため、mongodb の集計フレームワークで求めていることを達成する方法はありません (ただし、JIRA チケットはあります)。ただし、map-reduce を使用して目的を達成できるはずです。

// map function
function domap() {
    // turn ObjectId --> ISODate
    var date = this._id.getTimestamp();
    // format the date however you want
    var year = date.getFullYear();
    var month = date.getMonth();
    var day = date.getDate();

    // yields date string as key, entire document as value
    emit(year+"-"+month+"-"+day, this);
}

// reduce function
function doreduce(datestring, docs) {
    return {"date":datestring, "docs":docs};
}
于 2013-09-18T21:39:56.427 に答える
2

したがって、これは私の質問に直接答えるものではありませんが、Python の を使用して、上記のラムダのナンセンスをすべて置き換えるより良い方法を見つけましたsetdefault

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

ヒントをくれた @raymondh に感謝します。PyCon の話です。

コードを美しく慣用的な Python に変換する

于 2013-09-10T00:47:06.287 に答える