changing array inside the collection mongoDB - javascript

I am trying to change an array in my collection of users according to the id of an object I have in my array
it looks like this
_id:60a54bb0a5c5d25c9f4b83ea
email:"timotej"
pass:"$2b$10$hdvMb.PrcRmwNCqxcLpOmOLTvRTrMzHWAhPHWa4o4E.qOfuDTjeAm"
createdAt:2021-05-19T17:32:32.792+00:00
updatedAt:2021-05-23T11:32:37.882+00:00
__v:0
contacts:Array
0:Object
_id:"60aa3d3db9344014e5944291"
name:"contact1"
email:"contact1#mail.com"
phone:"0"
1:Object
_id:"60aa3d55b9344014e5944292"
name:"contact2"
email:"contact2#mail.com"
phone:"00"
Shema:
const mongoose = require('mongoose')
const Schema = mongoose.Schema;
const userSchema = new Schema({
email: {
type: String,
required: true,
unique: true
},
pass:{
type: String,
required: true
},
contacts:{
_id: {
type: String,
unique: true
},
name:{
type: String,
},
email:{
type: String
},
phone:{
type: String
}
}
}, {timestamps: true})
const User = mongoose.model('User', userSchema)
module.exports = User;
here is my code, I am trying to find the user by its email, and then the object in array contacts by its id and then update the contact.
const user = User.findOneAndUpdate(
{ email: mail.toLowerCase(), "contacts._id": req.params.id},
{ $set:{
"contacts.$._id": req.params.id,
"contacts.$.name": req.body.name,
"contacts.$.email": req.body.email,
"contacts.$.phone": req.body.phone,
}
},
{ multi: false }
).then((result) => {
console.log("result : " + result)
the data in req should be ok, but nothing is changing in my db when i send request

Related

MongoDB/GraphQL: Model.find() to get posts that userId is in likes

in my resolvers I have a method to find user likes with
async function userBookmarks(args, context) {
const user = checkAuth(context);
const posts = await Post.find({likes: {userId: user.id}})
return posts; }
But GraphQL returns an empty array.
For reference, the Post model is
likes: [
{
userId: String,
createdAt: String
}],
I came across a similar problem and fixed it by defining the MongoDB Collection name in the bottom of my MongoDB Schema.
const UserSchema = new mongoose.Schema({
firstName: {
type: String,
required: true
},
lastName: {
type: String,
required: true
},
email: {
type: String,
required: true
},
password: {
type: String,
required: true
},
location: {
type: String,
required: false
}
}, { collection : 'Users' });
EDIT:
Use $elemMatch to query several fields.
const posts = await User.find({likes: {$elemMatch: {userId: user.id}}})

MongoDB - how do I deep populate, an already populated field that has a reference to the schema it is in?

So I am having the following problem, I have a comments schema, which has a field called Replies and it is pointing toward the comment schema. The problem is that whenever I try to populate the following schema, everything except for the replies gets populated. Why is that happening, how do I fix it?
Comment Schema:
const {Schema, model} = require('mongoose')
const { ObjectId } = require('mongodb');
const commentSchema = new Schema({
Author:
{
type: ObjectId,
required: true,
ref: 'user'
},
Content:
{
type: String,
required: true
},
Likes:{
type: [ObjectId],
ref: 'user'
},
Replies: [this]
})
let comment = model('comment', commentSchema)
module.exports = comment
And that is how I populate the posts model:
let allPosts = await postModel
.find({})
.populate('Author Comments')
.populate(
(
{
path: 'Comments',
populate:[
{path: 'Author'}
]
},
{
path: 'Comments.Replies',
populate:[
{path: 'Author'}
]
}
)
)
and this is my post model, referenced in the previous code sample:
const {Schema, model} = require('mongoose')
const { ObjectId } = require('mongodb');
const postSchema = new Schema({
Author:
{
type: ObjectId,
required: true,
ref: 'user'
},
Content:
{
type: String,
required: true
},
Shares:{
type: [ObjectId],
ref: 'post'
},
Likes:{
type: [ObjectId],
ref: 'user'
},
Comments:{
type: [ObjectId],
ref: 'comment'
}
})
let post = model('post', postSchema)
module.exports = post

Unable to get _id which is not ObjectID with mongoose

I can't access to _id of any mongoose.model object. I know there are a lot of similar answers but none of it solved my problem. I am using mongoose and TypeScript.
I've existing collection which contains data with existing Mixed _id:
{
_id: 10,
name: "someString",
email: "someString",
}
...
I've Schema and interface:
const UserModel: Schema = new Schema({
name: { type: String, required: true },
email: { type: String, required: true, unique: true },
});
export interface IUser extends Document {
name: string;
email: string;
}
export default mongoose.model<IUser>('User', UserModel);
and I try to select some user:
UserModel.findOne({email:data.email}).then((user)=>{
console.log(user);
// I get everything without _id
// { name: "someString", email: "someString" }
console.log(user.id);
// null
});
Another attempt
I've also tried to set _id to false in options:
const UserModel: Schema = new Schema({
name: { type: String, required: true },
email: { type: String, required: true, unique: true },
}, { _id: false });
and I tried to select some user:
UserModel.findOne({email:data.email}).then((user)=>{
console.log(user);
// I get everything with _id
// { _id: 10, name: "someString", email: "someString" }
console.log(user.id, user._id);
// but it is not accessible
// null, undefined
});
Note
If I create document record through mongoose it creates _id as ObjectId() and it is selectable.
Mongoose expects an ObjectID for _id
Add your custom type to the schema
const UserModel: Schema = new Schema({
_id: { type: mongoose.Schema.Types.Mixed, required: true },
name: { type: String, required: true },
email: { type: String, required: true, unique: true },
});
The _id index can't be modified so don't worry about adding index options.
It's usually best to leave Mongo to use it's ObjectID.

How do you save certain items for specific users in mongodb?

I'm working on a job tracker app.
User creates an account, saving the user in a mongodb collection.
const UserSchema = new mongoose.Schema({
name: {
type: String,
required: true
},
email: {
type: String,
required: true
},
password: {
type: String,
required: true
},
date: {
type: Date,
default: Date.now
}
});
const JobSchema = new mongoose.Schema({
position: {
type: String,
required: true
},
company: {
type: String,
required: true
},
status: {
type: String,
default: "applied"
},
date: {
type: Date,
default: Date.now
}
});
When a user adds a job, how would you store (.post) and retrieve (.get) that data to correspond to that specific user only?
Is there a way to save the users "_id" to the jobs added, and searchById to get the jobs?
It depends what exactly you want to achieve meaning what type of relationships your models will have. Lets say your users will have multiple jobs the best approach would be to store an array of ObjectIds. The refoption tells mongoose which collections to search during population of the array
const UserSchema = new mongoose.Schema({
name: {
type: String,
required: true
},
email: {
type: String,
required: true
},
password: {
type: String,
required: true
},
date: {
type: Date,
default: Date.now
},
jobs: [{type:Schema.Types.ObjecId,ref: 'Job'}]
});
and then when you query the database you chain populate('jobs') after the query.
You can read more on the subject here
For example,
const UserSchema = new mongoose.Schema({
name: {
type: String,
required: true
},
email: {
type: String,
required: true
},
password: {
type: String,
required: true
},
date: {
type: Date,
default: Date.now
}
});
const User = mongoose.model('User', UserSchema);
async function updateUser() {
let user = await User.findOne({"name": "a-unique-user-name-in-the-db"})
let userId = user._id
let newEmail = "asdf#asdf.com"
let updated = await User.updateOne(
{ "_id": userId },
{
$set: {
"email": newEmail,
}
}
)
if (updated) {
console.log("updated")
}
}
updateUser();

Try to populate in mongoose and it doesn't work (nodejs)

i Make mini cart with Product and user Auth, Evereting work perfect but whan i try to make a route that pickup all the product from the user and view them in specific page and it not work for me.
it returns the user but not the product.
UserSchema
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const UserSchema = new Schema({
product: {
type: [mongoose.Schema.Types.ObjectId],
ref: "product"
},
name: {
type: String,
required: true
},
email: {
type: String,
required: true,
unique: true
},
address: {
type: String,
required: true
},
password: {
type: String,
required: true
},
data: {
type: Date,
default: Date.now
}
});
module.exports = User = mongoose.model("user", UserSchema);
ProductScheama
const mongoose=require('mongoose');
const ProductSchema = new mongoose.Schema({
name:{
type:String,
required:true,
unique:true
},
description:{
type:String,
},
price:{
type:Number,
required:true
},
quantity:{
type:Number,
required:true
},
data:{
type:Date,
default:Date.now
}
})
module.exports=Product=mongoose.model('product',ProductSchema)
I am trying to create a function that gives me the name, price and description of the product and it fails.
my router:
router.get("/products/:id", auth, async (req, res) => {
try {
let pro = await User.find({ product: req.params.id }).populate("product", [
"name",
"price",
"description"
]);
if (!pro) {
return res.json({ msg: "This user not have products to show" });
}
res.json(pro);
} catch (err) {
console.error(err.message);
res.status(500).send("Server errors");
}
});
result from Postman:
[
{
"product": [],
"_id": "5d5bfb96963ca600ec412bca",
"name": "Anonny Annon",
"email": "Annony#gmail.com",
"address": "Israel",
"password": "$2a$10$gESTIaBVifzhRDR2zOKsw.Q79gCT07IK2VnDoyT2oU5htqfBuAj8W",
"data": "2019-08-20T13:54:30.267Z",
"__v": 0
}
]
I think product should be defined this way :
product: [{
type: mongoose.Schema.Types.ObjectId,
ref: "product"
}]
instead of type: [mongoose.Schema.Types.ObjectId]
Solution found here

Categories

Resources