2010-11-23 17 views
62

Usando Mongoid. Desafortunadamente, Mongoid no permite seleccionar únicos/distintos. Han obtenido estos resultados. Como puede ver, hay 7 resultados. Si miras detenidamente (en user_id), solo hay 2 usuarios.¿Cómo obtengo elementos únicos en esta matriz?

[ 
    #<Activity _id: 4cea6c4572357e00fa00011a, created_at: 2010-11-22 13:12:37 UTC, updated_at: 2010-11-22 13:12:37 UTC, action: "Attend", user_id: BSON::ObjectId('4cea2fb872357e00fa000025'), artist_id: nil, media_id: BSON::ObjectId('4cea447472357e00fa00009a')>, 
    #<Activity _id: 4cea6c3072357e00fa000116, created_at: 2010-11-22 13:12:16 UTC, updated_at: 2010-11-22 13:12:16 UTC, action: "Attend", user_id: BSON::ObjectId('4cea2fb872357e00fa000025'), artist_id: nil, media_id: BSON::ObjectId('4cea447472357e00fa00009a')>, 
    #<Activity _id: 4cea6bdd72357e00fa00010d, created_at: 2010-11-22 13:10:53 UTC, updated_at: 2010-11-22 13:10:53 UTC, action: "Attend", user_id: BSON::ObjectId('4cea2fb872357e00fa000025'), artist_id: nil, media_id: BSON::ObjectId('4cea447472357e00fa00009a')>, 
    #<Activity _id: 4cea46df72357e00fa0000a4, created_at: 2010-11-22 10:33:03 UTC, updated_at: 2010-11-22 10:33:03 UTC, action: "Attend", user_id: BSON::ObjectId('4cea2fb872357e00fa000025'), artist_id: nil, media_id: BSON::ObjectId('4cea447472357e00fa00009a')>, 
    #<Activity _id: 4cea40c572357e00fa00006f, created_at: 2010-11-22 10:07:01 UTC, updated_at: 2010-11-22 10:07:01 UTC, action: "Attend", user_id: BSON::ObjectId('4cea2fb872357e00fa000025'), artist_id: nil, media_id: BSON::ObjectId('4cea3c8b72357e00fa00005e')>, 
    #<Activity _id: 4cea3ca172357e00fa000062, created_at: 2010-11-22 09:49:21 UTC, updated_at: 2010-11-22 09:49:21 UTC, action: "Attend", user_id: BSON::ObjectId('4cea39b772357e00fa000046'), artist_id: nil, media_id: BSON::ObjectId('4cea3c8b72357e00fa00005e')>, 
    #<Activity _id: 4cea344a72357e00fa00003f, created_at: 2010-11-22 09:13:46 UTC, updated_at: 2010-11-22 09:13:46 UTC, action: "Attend", user_id: BSON::ObjectId('4cea2fb872357e00fa000025'), artist_id: nil, media_id: BSON::ObjectId('4cea306c72357e00fa000031')> 
] 

que estaba viendo this, y estaba pensando que podría hacer algo similar para que mi matriz sería ahora el siguiente aspecto:

[ 
    #<Activity _id: 4cea6c4572357e00fa00011a, created_at: 2010-11-22 13:12:37 UTC, updated_at: 2010-11-22 13:12:37 UTC, action: "Attend", user_id: BSON::ObjectId('4cea2fb872357e00fa000025'), artist_id: nil, media_id: BSON::ObjectId('4cea447472357e00fa00009a')>, 
    #<Activity _id: 4cea3ca172357e00fa000062, created_at: 2010-11-22 09:49:21 UTC, updated_at: 2010-11-22 09:49:21 UTC, action: "Attend", user_id: BSON::ObjectId('4cea39b772357e00fa000046'), artist_id: nil, media_id: BSON::ObjectId('4cea3c8b72357e00fa00005e')> 
] 

No me preocupa que se extraen combinación de resultados. Siempre que tenga user_id's únicos en el conjunto de resultados. Alguien sabe cómo se puede lograr esto?

Respuesta

174

Puede usar el método uniq. Asumiendo que su matriz es ary, llame a:

ary.uniq{|x| x.user_id} 

y esto va a devolver un conjunto único con user_id s.

+18

Esta es una solución rápida al problema del OP, pero a la larga fomenta el sorber todos los datos y luego iterar sobre él para eliminar los duplicados. Eso consumirá más recursos de los necesarios. Una mejor solución es que el OP use una consulta más inteligente que elimine los engaños por adelantado, o un tipo de colección que los elimine por naturaleza. –

+4

@Greg: sí, estoy de acuerdo, pero asegúrese de que no está haciendo una optimización prematura tampoco ... – Peter

+16

Eso no es prematuro, son más de 30 años de experiencia en el manejo de bases de datos. –

1

En lugar de utilizar una matriz, considere utilizar Hash o Set.

Los conjuntos se comportan de forma similar a una matriz, solo que contienen solo valores únicos y, debajo de las cubiertas, se crean en hash. Los conjuntos no conservan el orden en que se colocan los elementos a diferencia de las matrices. Los hashes tampoco conservan el orden, pero se puede acceder a través de una clave para que no tenga que recorrer el hash para encontrar un elemento en particular.

Estoy de acuerdo con Hashes. En su aplicación, user_id podría ser la clave y el valor sería el objeto completo. Eso eliminará automáticamente cualquier duplicado del hash.

O, solo extraiga valores únicos de la base de datos, como sugirió John Ballinger.

0

Errr, es un poco complicado en la vista. Pero creo que he conseguido que funcione con el grupo (http://mongoid.org/docs/querying/)

controlador

@event_attendees = Activity.only(:user_id).where(:action => 'Attend').order_by(:created_at.desc).group 

Ver

<% @event_attendees.each do |event_attendee| %>  
    <%= event_attendee['group'].first.user.first_name %> 
<% end %> 
15

Esto debería funcionar para que:

Considere la Tabla 1 tiene una columna con el nombre de la actividad que puede tener el mismo valor en más de un registro. Así es como extraerá SOLAMENTE las entradas únicas del campo de actividad dentro de la Tabla1.

#An array of multiple data entries 
@table1 = Table1.find(:all) 

#extracts **activity** for each entry in the array @table1, and returns only the ones which are unique 

@unique_activities = @table1.map{|t| t.activity}.uniq 
10

Para aquellos golpear esto en el futuro, ahora se puede utilizar el método Mongoid::Criteria#distinct de Origen para seleccionar sólo valores únicos de la base de datos:

# Requires a Mongoid::Criteria 
Attendees.all.distinct(:user_id) 

http://mongoid.org/en/mongoid/docs/querying.html (v3.1.0)

Cuestiones relacionadas