0

I am trying to query a subdocument array named cars. Here i have all the dealer's cars for sale. I can return the parent document with all the cars in it, but i can not query the subdocuments. and When i try to do it, i only get one subdocument, when there is more in the DB, or all of them - i hope you can help me out

My Schema

var mongoose = require('mongoose');

var bilerSchema = new mongoose.Schema({
    maerke: String,
    model: String,
    titel: String,
    thtitel: String,
    hk :String,
    nm :String,
    nultilhundrede :String,
    tophastighed :String,
    kmprliter :String,
    bredde:String,
    laengde :String,
    hoejde :String,
    Lasteevne :String,
    traekhjul :String,
    maxpaahaeng :String,
    airbags :String,
    tank :String,
    gear :String,
    geartype :String,
    vaegt :String,
    dore :String,
    motor :String,
    braendstof :String,
    leveringspris:String,
    farve :String,
    beskrivelse: String,
    udstyr: [String],
    aargang :String,
    km :String,
    pris :String,
    indregistrering: String,
    synet :String,
    images: [String],
},{ timestamps: { createdAt: 'created_at' } });

var carSchema = new mongoose.Schema({
    ownerID: String,
    cars: [bilerSchema]
});

const Car =  module.exports =  mongoose.model('Car', carSchema);

I first get the parentdocument by ownerID, and after that i want to query the subdocument, to only contain document which fulfils criteria. ex. if i want to return all the cars which is make BMW, og fuel is Diesel, and so on.

What i accomplished,

The method that is commented out, return only on Diesel car, and the other method thats not commented out returns all cars in subdocument,

console.log(query);

    Biler.findOne({ownerID:id, cars:{ $elemMatch :{braendstof: "Benzin"}}})
        .exec((err,doc)=>{
        console.log(doc);
        res.json(doc);
    });
    // Biler.find({ownerID: id}, {cars: {$elemMatch:{'braendstof':'Diesel'}}})
    //     .exec((err,doc) =>{
    //         var response = {
    //             status : 200,
    //             message : doc[0].cars
    //         };
    //         if (err) {
    //             console.log("Error finding car");
    //             response.status = 500;
    //             response.message = err;
    //         } else if(!doc) {
    //             console.log("Forhandler ID not found in database", id);
    //             response.status = 404;
    //             response.message = {
    //                 "message" : "Forhandler ID not found " + id
    //             };
    //         }
    //         res
    //             .status(response.status)
    //             .json(response.message);
    //     });
  • As noted in the answers `$elemMatch` on it's own on correctly selects the "document" that contains the matching array entries. In fact if you only want one property of the array to match it is not needed and you need only do. `.find({ "cars.braendstof": "Benzin" })`. – Neil Lunn Aug 03 '17 at 00:41
  • If you want "multiple" properties, that is when you use `$elemMatch`. i.e `.find({ "cars": { "$elemMatch": { "braendstof": "Diesel", "maerke": "BMW" } } })`. But without "projection", all the "array" elements are returned. – Neil Lunn Aug 03 '17 at 00:45
  • Use the [positional `$` operator](https://docs.mongodb.com/manual/reference/operator/projection/positional/) to return the "first" match. For "multiple matches" use [`$filter`](https://docs.mongodb.com/manual/reference/operator/aggregation/filter/). i.e `{ "$filter": { "input": "$cars", "as": "c", "cond": { "$and": [{ "$eq": [ "$$c.braendstof", "Benzin" ] }, { "$eq": [ "$$c.maerke", "BMW" ] }] } } }`. More details in the full answers, but that's the gist as applied to this question. – Neil Lunn Aug 03 '17 at 00:45

0 Answers0