2012-08-15 14 views
26

Por ejemplo, hay una colección como esta:
¿Cómo realizar eficientemente "distinct" con múltiples claves?

{mercado: 'SH', código: '000001', fecha: '2012-01-01', precio: 1000} {
mercado : 'SZ', código: '000001', fecha: '2012-01-01', precio: 1000}
{mercado: 'SH', código: '000001', fecha: '2012-01-02', precio: 1000}
{mercado: 'SZ', código: '000001', fecha: '2012-01-02', precio: 1000}
{mercado: 'SH', código: '000002', fecha: '2012-01-03', precio: 1000}
...

Esta colección contiene decenas de millones de documentos.

Quiero llamar distinta con dos claves:

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

y obtener resultado:

[{mercado: 'SH', código: '000001'}, {mercado: 'SZ', código: '000001'}, { mercado: 'SH', código: '000002'}]

Como nativa de comandos distinta aceptar sólo una tecla, trato de poner en práctica usando map-reduce. Pero map-reduce es demasiado lento para ser nativo distinto. En mi prueba única de una tecla, map-reduce gastar unas diez veces más que el native distinct.
¿Existe una forma eficiente de implementar varios señuelos distintos?

Respuesta

53

Si usted está dispuesto a esperar a la próxima 2.2 liberación de MongoDB, puede ejecutar esta consulta de manera eficiente utilizando el marco de la agregación:

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

En una colección de millones de registro en mi máquina de prueba, este corrió en 4 segundos, mientras que la versión de mapa/reducir tomó más de un minuto.

Cuestiones relacionadas