Aquí hay un ejemplo que usa Aggregation Framework en MongoDB 2.4.9 que creo que logra el resultado que busca:
db.books.aggregate(
// Unwind the refs array
{ $unwind: "$refs" },
// Sort by refs.default descending so "true" values will be first, nulls last
{ $sort: {
"refs.default" : -1
}},
// Group and take the first ref; should either be "default:true" or first element
{ $group: {
_id: "$_id",
name: { $addToSet: "$name" },
refs: { $first: "$refs" }
}},
// (optional) Sort by name to match the example output
{ $sort: {
name: 1,
}},
// (optional) Clean up output
{ $project: {
_id: 0,
name: 1,
refs: 1
}}
)
Resultado de la muestra:
{
"result" : [
{
"name" : [
"Book1"
],
"refs" : {
"oid" : "object5",
"default" : true
}
},
{
"name" : [
"Book2"
],
"refs" : {
"oid" : "object5",
"default" : true
}
},
{
"name" : [
"Book3"
],
"refs" : {
"oid" : "object4"
}
},
{
"name" : [
"Book4"
],
"refs" : {
"oid" : "object4",
"default" : true
}
}
],
"ok" : 1
}
Notas:
-
Esto hace una suposición sobre el comportamiento del orden de clasificación para
refs
donde falta "predeterminado:verdadero". Tras una prueba breve, parece que se ha conservado el orden original, por lo que el "primer" elemento de la matriz es el esperado. -
Debido a los operadores de agregación utilizados, la salida
name
es una matriz de un solo elemento, yrefs
se convierte en un objeto incrustado. En lugar de seguir manipulando en el marco de agregación, simplemente podría hacer referencia a los campos correctos en el código de su aplicación.