0

Users are able to post items which other users can request. So, a user creates one item and many users can request it. So, I thought the best way would be to put an array of users into the product schema for who has requested it. And for now I just want to store that users ID and first name. Here is the schema:

const Schema = mongoose.Schema;

const productSchema = new Schema({
    title: {
        type: String,
        required: true
    },
    category: {
        type: String,
        required: true
    },
    description: {
        type: String,
        required: true
    },
    userId: {
        type: Schema.Types.ObjectId,
        ref: 'User',
        required: true
    },
    requests: [
        {
            userId: {type: Object},
            firstName: {type: String}

        }
    ],
});

module.exports = mongoose.model('Product', productSchema);

In my controller I am first finding the item and then calling save().

exports.postRequest = (req, res, next) => {
  const productId = req.body.productId;
  const userId = req.body.userId;
  const firstName = req.body.firstName;
  const data = {userId: userId, firstName: firstName};
  Product.findById(productId).then(product => {
    product.requests.push(data);
    return product
      .save()
      .then(() => {
        res.status(200).json({ message: "success" });
      })
      .catch(err => {
        res.status(500).json({message: 'Something went wrong'});
      });
  });
};

Firstly, is it okay to do it like this? I found a few posts about this but they don't find and call save, they use findByIdAndUpdate() and $push. Is it 'wrong' to do it how I have done it? This is the second way I tried it and I get the same result in the database:

exports.postRequest = (req, res, next) => {
    const productId = req.body.productId;
    const userId = req.body.userId;
    const firstName = req.body.firstName;
    const data = {userId: userId, firstName: firstName};
    Product.findByIdAndUpdate(productId, {
        $push: {requests: data}
    })
    .then(() => {
        console.log('succes');
    })
    .catch(err => {
        console.log(err);
    })
  };

And secondly, if you look at the screen shot is the data in the correct format and structure? I don't know why there is _id in there as well instead of just the user ID and first name. enter image description here

2 Answers 2

1

Normally, Developers will save only the reference of other collection(users) in the collection(product). In addition, you had saved username also. Thats fine.

Both of your methods work. But, second method has been added in MongoDB exactly for your specific need. So, no harm in using second method.

Sign up to request clarification or add additional context in comments.

8 Comments

you have touched on what I wanted to know. Using mysql I would have done this differently and created a table join for all the requests but I thought that the point of mongo was to not really use it as a relational database. That is why I thought perhaps I could put the users details into that array so I wouldn't have to join tables using the User ID in order to get the users name and email address etc.
Mongo is noSQL database. But, it supports joins through $lookup(aggregation). Also, keeping a reference helps us updating collection with only related data.
okay, so you are saying I should just save the userId and not their name as well like I have?
You could save., as it is your code. But, to keep collections non-polluted, you can just save the reference.
Ah, okay. So it's normal. I thought I had done something wrong :)
|
1

There is nothing wrong doing it the way you have done it. using save after querying gives you the chance to validate some things in the data as well for one. and you can add additional fields as well (if included in the Schema). for an example if your current json return doesn't have a field called last_name then you can add that and save the doc as well so that's a benefit..

When using findById() you don't actually have the power to make a change other than what you program it to do

One thing I noticed.. In your Schema, after you compile it using mongoose.modal()

export the compiled model so that you can use it everywhere it's required using import. like this..

const Product = module.exports = mongoose.model('Product', productSchema);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.