0

I'm building an API in NodeJS Express and MongoDB using Mongoose. I created a Profile model that embeds the Experience schema. Like:

{
    "_id": "5e26ff6d5be84a3aeeb2f7bb",
    "username": "some"
    <fields of the profile>
    "experience": [
        {
            "image": "",
            "createdAt": "2020-01-21T13:41:01.873Z",
            "updatedAt": "2020-01-21T13:41:01.873Z",
            "_id": "5e26ff6d5be84a3aeeb2f7bc",
            "title": "Senior Dev",
            "role": "Dev",
            "company": "ArosaDev",
            "startDate": "2018-12-03T23:00:00.000Z",
            "endDate": null,
            "description": "",
            "area": ""
        }
    ],
    "createdAt": "2020-01-21T13:41:01.874Z",
    "updatedAt": "2020-01-21T13:41:01.874Z",
    "__v": 0
}

The problem is I have to create an endpoint GET which gets for one profile all the experiences.

experienceRouter.get("/:username", async(req, res) => {

    console.log(req.params.username);

    const experiences = await Profiles.findOne({"username":req.params.username} ??? );

    res.send(experiences);
});

I know I should select the embedded field experience and get back all the experiences but I don't know how should I do with Mongoose in my route.

I don't know what comes next after I select the username and how I can select the all experience for the username I'm requested.

I'm new to this and cannot find any good references explaining to me that for good.

I will appreciate an example of how a route like this should be done.

My model:

// Profile Schema model
// Embedded we have the Experience as []
const mongoose = require("mongoose");
const { isEmail } = require("validator");


const experienceSchema = new mongoose.Schema({

        title: {
            type: String,
            required: true
        },
        role: {
            type: String,
            required: true
        },
        company: {
            type: String,
            required: true
        },
        startDate: {
            type: Date,
            required: true
        },
        endDate: {
            type: Date
        },
        description: {
            type: String
        },
        area: {
            type: String
        },
        createdAt: {
            type: Date,
            default: Date.now,
            required: false
        },

        updatedAt: {
            type: Date,
            default: Date.now,
            required: false
        },

        image: {
            type: String,
            required: false,
            default: "https://via.placeholder.com/150"
        }

})



const profileSchema = new mongoose.Schema({

    firstname: {
        type: String,
        required: true
    },

    surname: {
        type: String,
        required: true
    },

    email: {
        type: String,
        trim: true,
        lowercase: true,
        unique: true,
        required: true,
        validate: {
            validator: string => isEmail(string),
            message: "Provided email is invalid"
        }
    },

    bio: {
        type: String,
        required: true
    },

    title: {
        type: String,
        required: true
    },

    area: {
        type: String,
        required: true
    },

    imageUrl: {
        type: String,
        required: false,
        default: "https://via.placeholder.com/150"
    },

    username: {
        type: String,
        required: true,
        unique: true
    },

    experience: [
        experienceSchema
    ],

    createdAt: {
        type: Date,
        default: Date.now,
        required: false
    },

    updatedAt: {
        type: Date,
        default: Date.now,
        required: false
    }
});

const collectionName = "profiles";
const Profile = mongoose.model(collectionName, profileSchema);

module.exports = Profile;
Jakub
  • 2,367
  • 6
  • 31
  • 82
  • DO you want to reference `experience` schema with `profiles`? and want to get all experiences of specific user? – Fahad Hassan Jan 22 '20 at 09:56
  • I have to use the embedded design way as I showed in my model and my goal is that I want to get a profile by username and get its experiences only. Example of output: {_id .. username ... expereince[experiences]} so I see all the experiences for that one profile – Jakub Jan 22 '20 at 09:58

1 Answers1

1

replace your code with below

You can mention your fields which you need in the second argument of function this is called projection as mentioned

So for including of fields use 1 and for excluding fields use 0

experienceRouter.get("/:username", async(req, res) => {

    console.log(req.params.username);

    const profile = await Profiles.findOne({"username":req.params.username},{experience:1 ,username:1, _id:0}).lean();

    res.send(profile);
});
p u
  • 1,395
  • 1
  • 17
  • 30
  • Is this get all the experiences I have in the []? – Jakub Jan 22 '20 at 10:00
  • @Jakub yes, it will fetch all data which is present in ```experience``` key – p u Jan 22 '20 at 10:02
  • And if I want to add just before the result the username I requested like {username: Jakub, experience: []} and a count also? :) – Jakub Jan 22 '20 at 10:04
  • you can fetch any field which is mentioned in your schema like username just add ```username:1``` and count of which field you want? – p u Jan 22 '20 at 10:08
  • Sorry I'm new in this can you correct me please: const profile = await Profiles.findOne( { username: req.params.username }, { "username":1}, { "experience": 2, _id: 0 } ).lean(); – Jakub Jan 22 '20 at 10:14
  • no problem @Jakub edited my answer. give it +1 if it helped you :) – p u Jan 22 '20 at 10:20
  • I did but error UnhandledPromiseRejectionWarning: MongoError: Projection cannot have a mix of inclusion and exclusion. – Jakub Jan 22 '20 at 10:30
  • may you can help me with this also https://stackoverflow.com/questions/59859173/how-to-populate-in-nodejs-and-mongoose-a-post-which-need-to-be-referred-to-a-use @p u – Jakub Jan 22 '20 at 12:00