2016-08-30 3 views
2

Am mit dem folgenden Mongoose Schema in meiner Knoten-Anwendung mit Fundin einem Array von Objekten Schema mit Mongoose

var expenseSchema = new Schema({ 
    particular : String, 
    date : {type : Date, default: Date.now}, 
    paid_by : String, 
    amount : Number, 
    month : String 
}); 

var roomSchema = new Schema({ 
    name: String, 
    admin: String, 
    roomies : [String], 
    expenses : [expenseSchema] 
},{ 
    collection : 'rooms' 
}); 

Ich brauche für einen bestimmten Monat mit find() Kosten für ein Zimmer zu bekommen. Hier ist das, was ich habe versucht, aber es gibt mir das ganze Zimmer Objekt

Room.findOne({_id : req.params._id, 'expenses.month' : 'oct'}).exec(function(err, result){ 
     if(result == null) { 
      res.json({result : 'Oops! We couldn\'t find any rooms...'});    
     } else if(err) { 
      res.json({result : 'Error in getting Rooms'}); 
     } else { 
      res.json({result : result}); 
     } 
    }); 

jemand mir dabei helfen?

Antwort

0

Sie die positional $ operator in Ihrem projection können Sie die passende Ausgaben Array Element in Ihrem Ergebnis zurück:

Room.findOne(
    { "_id": req.params._id, "expenses.month": "oct" }, 
    { "expenses.$": 1 } 
).exec(callback); 

oder für mehrere Übereinstimmungen könnten Sie die $filter Betreibers Aggregation Framework verwenden in der $project Pipeline wie:

var ObjectId = mongoose.Types.ObjectId; 
Room.aggregate() 
    .match({ "_id": new ObjectId(req.params._id), "expenses.month": "oct" }) 
    .project({ 
     "expenses": { 
      "$filter": { 
       "input": "$expenses", 
       "as": "item", 
       "cond": { "$eq": [ "$$item.month", "oct" ] } 
      } 
     } 
    }) 
    .exec(callback); 

oder wenn Sie eine ältere Version verwenden o f Mungo-Treiber, der keine Unterstützung für die MongoDB 3.2 $filter, könnten Sie $map neben $setDifference verwenden, wo Sie "Filter" Array Inhalte ohne $unwind:

var ObjectId = mongoose.Types.ObjectId; 
Room.aggregate([ 
    { "$match": { "_id": new ObjectId(req.params._id), "expenses.month": "oct" } },   
    { "$project": { 
     "expenses": { 
      "$setDifference": [ 
       { 
        "$map": { 
         "input": "$expenses", 
         "as": "items", 
         "in": { 
          "$cond": [ 
           { "$eq": [ "$$items.month", "oct" ] }, 
           "$$items", 
           false 
          ] 
         } 
        } 
       }, 
       [false] 
      ] 
     } 
    } } 
], function(err, results){   
    console.log(JSON.stringify(results[0], null, 4)); 
}); 
+0

Dies gibt nur die richtigen Daten zurück. Aber es gibt nur ein Objekt zurück. Wie kann ich alle Objekte im Array mit demselben Monat erhalten? –

+0

Dies gibt ein leeres Objekt zurück –

+0

Ich denke, ich weiß warum, weil mit 'aggregate()' -Funktion für '$ match' mit' _id' übereinzustimmen, zuerst Werte zu 'ObjectId' umgewandelt werden müssen. Überprüfen Sie meine aktualisierte Version. – chridam

0

dies Unter der Annahme, arbeiten können

var expenseSchema = new Schema({ 
    particular : String, 
    date : {type : Date, default: Date.now}, 
    paid_by : String, 
    amount : Number, 
    month : String 
}); 

var roomSchema = new Schema({ 
    name: String, 
    admin: String, 
    roomies : [String], 
    expense_id : type: Schema.Types.ObjectId, ref: 'expenseSchema' 
},{ 
    collection : 'rooms' 
}); 



Room.findOne({expense_id: req.params._id , "expenses.month": "oct" }) 
        .populate('expense_id') 
        .exec(function (err, doc) { 
         if (err) { 
          throw err 
         } 
         console.log(doc) 
         }) 
+0

Da ich alle POST-Methoden geschrieben habe, wäre es großartig, wenn es eine Lösung geben könnte, ohne das Schema ändern zu müssen. Können Sie eine Lösung mit demselben Schema vorschlagen? –

0
Room.findOne({ 
       _id : req.params._id, 
       'expenses.month':'oct' 
      },{ 
       'expenses': { 
       $elemMatch:{ 
        'month':'oct' 
       } 
       } 
      ).exec(
       function(err, result){ 
       if(result == null) { 
        res.json({result : 'Oops! We couldn\'t find any rooms...'});    
       } else if(err) { 
        res.json({result : 'Error in getting Rooms'}); 
       } else { 
        res.json({result : result}); 
       } 
      }); 
+0

kein Glück damit. –

+0

warum? '$ elemMatch' funktioniert super und sollte korrekt sein. – gianlucatursi

+0

es gibt mich immer noch mit Daten von Monat == Sept. –

Verwandte Themen