How to efficiently perform "distinct" with multiple keys?

Mongodb

Mongodb Problem Overview


For example, there is a collection like this:

> {market: 'SH', code: '000001', date: '2012-01-01', price: 1000}
{market: 'SZ', code: '000001', date: '2012-01-01', price: 1000}
{market: 'SH', code: '000001', date: '2012-01-02', price: 1000}
{market: 'SZ', code: '000001', date: '2012-01-02', price: 1000}
{market: 'SH', code: '000002', date: '2012-01-03',price: 1000}
...

This collection contains tens of millions documents.

I want to call distinct with two keys:

collection.distinct('market', 'code');

and get result :

> [{market: 'SH', code:'000001'}, {market: 'SZ', code:'000001'}, {market: 'SH', code:'000002'}]

As native distinct command accept only one key, I try to implement it by using map-reduce. But map-reduce is far too slow to native distinct. In my one-key distinct test, map-reduce spend about ten times longer than native distinct.
Is there a efficient way to implement multikey distinct?

Mongodb Solutions


Solution 1 - Mongodb

If you are willing to wait for the upcoming 2.2 release of MongoDB, you can run this query efficiently using the aggregation framework:

collection = db.tb;
result = collection.aggregate( 
            [
                {"$group": { "_id": { market: "$market", code: "$code" } } }
            ]
        );
printjson(result);

On a million-record collection on my test machine, this ran in 4 seconds, while the map/reduce version took over a minute.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser805627View Question on Stackoverflow
Solution 1 - MongodbWilliam ZView Answer on Stackoverflow