How to define a schema that works with React and Graphql promise based.
const Cat = mongoose.model('Cat', { name: String });
You can define your schema like this:
const userSchema = new mongoose.Schema(
{
__id: mongoose.Schema.Types.ObjectId,
email: {
type: String,
required: true
},
name: {
type: String,
required: true
},
password: {
type: String
}
},
{
timestamps: true
}
)
Related
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 documents contain an array of objects and what is the best way to query those documents if I want to find and remove an object from an array with some specific value;
Here is an example of the document schema
const mongoose = require("mongoose");
const LibrarySchema = new mongoose.Schema({
user: {
type: mongoose.Schema.Types.ObjectId,
required: true,
},
books: [
{
type: new mongoose.Schema({
bookName: {
type: String,
required: true,
},
chapterReading: {
type: Number,
default: 1,
required: true,
},
}),
},
],
});
const Library = mongoose.model("Library", LibrarySchema);
exports.Library = Library;
If I want to find and remove a book with some bookName
Use $pull
Example :
Library.update({}, { $pull: { books: { bookName: "Yourbookname" } } })
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.
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();
I am trying to associate various login methods with the same User model in mongo.
const UserSchema = new Schema({
email: String
isVerified: { default: false, type; Boolean }
accounts: {
ref: 'Account',
type: Schema.Types.ObjectId
}
})
const AccountSchema = new Schema({
facebook: {
ref: 'FacebookAccount',
type: Schema.Types.?
},
local: {
ref: 'LocalAccount',
type: Schema.Types.?
},
twitter: {
ref: 'TwitterAccount',
type: Schema.Types.?
},
})
const LocalAccount = new Schema({
email: String,
name: String,
phone: String,
password: String,
_user: {
ref: 'User',
type: Schema.Types.ObjectId
}
})
What I would like to get the data coming back to me looking like would be:
{
_id: '12345789',
email: 'turdFerguson#gmail.com',
accounts: {
facebook: { ... }
local: { ... }
}
}
I'm really unsure about these associations though hence Schema.Types.? on the individual accounts. Also unsure if I should be using embedded vs object reference and where is appropriate. I'm going in circles trying to get the associations to match up.
I suggest you keep it simple with embedded.
Here is a quick suggestion:
const UserSchema = new Schema({
isVerified: {
default: false,
type: Boolean
},
accounts: {
local: {
email: String,
name: String,
phone: String,
password: String
},
facebook: {
// fields related to Facebook
},
twitter: {
// fields related to Twitter
}
}
})
I removed email as it seems redundant to have it since you already have accounts.local.email