Hier ist ein Beispiel mit dem Aggregation Framework in MongoDB 2.4.9, das meiner Meinung nach das gewünschte Ergebnis erzielt:
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
}}
)
Beispielergebnis:
{
"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
}
Hinweise:
-
Dies macht eine Annahme über das Verhalten der Sortierreihenfolge für
refs
wo "default:true" fehlt. Bei kurzen Tests scheint die ursprüngliche Reihenfolge beibehalten zu werden, also ist das "erste" Element des Arrays wie erwartet. -
Aufgrund der verwendeten Aggregationsoperatoren ist die Ausgabe
name
ist ein einzelnes Elementarray undrefs
wird zu einem eingebetteten Objekt. Anstatt das Aggregation Framework weiter zu manipulieren, könnten Sie einfach auf die richtigen Felder in Ihrem Anwendungscode verweisen.