How to find a document in mongoose by child property? - javascript

I have this Person and User models in my project:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const schema = new Schema({
name: {
type: String,
required: true
}
});
module.exports = mongoose.model('Person', schema);
and
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const schema = new Schema({
person: {
type: mongoose.SchemaTypes.ObjectId,
ref: 'Person',
required: true
},
email: {
type: String,
required: true
}
});
module.exports = mongoose.model('User', schema);
As we can see, a User has a reference to Person. I'm trying to find one User by either his email or by name of his Person. I tried many different approaches, like this:
exports.getUserByPersonNameOrEmail = async (uservalue) => {
var user = await User.findOne({
$or: [
{"person.name": uservalue},
{email: uservalue}
]
});
return user;
};
I also read about using the $elemMatch command, but it seems that it is used for documents with an array of children, instead of a specific child.

You would have to use mongoose populate and its match step during populate:
var user = await User.findOne({}).populate({
path: 'person',
match: { name: uservalue },
select: 'name -_id'
}).exec()
You can read more about it here. The idea basically is that you have to populate the actual references to person in your use model in order to query them. match applies a filter while they are being populated etc.

Related

How to insert data into MongoDB collection?

I'm using NodeJS with Mongoose. I've two tables into db.js:
const mongoose = require('mongoose')
const UserSchema = new mongoose.Schema(
{
username: { type: String, required: true, unique: true },
email: { type: String, required: true, unique: true },
password: { type: String, required: true }
},
{ collection: 'users' }
)
const model = mongoose.model('UserSchema', UserSchema)
const AccountSchema = new mongoose.Schema(
{
username: { type: mongoose.Schema.Types.ObjectId, required: true, ref: 'hahaha' },
balance: { type: Number, required: true }
},
{ collection: 'accounts' }
)
module.exports.UserSchema = model
module.exports.AccountSchema = model
As you can see the first collection contains users (username, email, password). The second collection represents a bank account, related to a specific user. So, it has two fields: user (foreign key) and balance ($100, i.e.). First question: is my code correct to accomplish this task?
Second question: how can I insert data into the AccountSchema?
I obviously want to insert data only if the user exists into Userschema. I think that this doesn't work:
const Schema = require('./model/db')
app.post('/api/addaccount', async (req, res) => {
const { username, balance } = req.body
try {
const response = await Schema.AccountSchema.create({
username,
balance
})
console.log('User account successfully: ', response)
res.json({status : "ok"})
} catch (error) {
throw error
}
})
How can I do this?
This won't work. You've to query the User model first to check if any user exists with this username. If yes, you'll continue to store data in the Account model, if not you'll return a response something like user doesn't exist

Getting invalid schema error, when having array of mongoose schema objects

Here is my schema for userPost.js:
const mongoose = require("mongoose");
let userPostSchema = new mongoose.Schema({
id:{
type: mongoose.Types.ObjectId
},
body:{
type: String
}
}, {timestamps: true});
const UserPost = mongoose.model("post", userPostSchema);
module.exports = UserPost;
Here is my schema for userAccount.js:
const userPost = require("./UserPost");
const mongoose = require("mongoose");
let userAccountSchema = new mongoose.Schema({
id:{
type: mongoose.Types.ObjectId
},
name:{
type: String
},
posts:
{
type: [userPost]
}
}, {timestamps: true});
let userAccount = mongoose.model("account", userAccountSchema);
module.exports = userAccount;
I am getting the posts error:
node_modules\mongoose\lib\schema.js:984
throw new TypeError('Invalid schema configuration: ' +
^
TypeError: Invalid schema configuration: `model` is not a valid type within the array `posts`.See http://.../mongoose-schematypes for a list of valid schema types.
at Schema.interpretAsType (C:\Users\BackEnd\node_modules\mongoose\lib\schema.js:984:15)
at Schema.path (C:\Users\BackEnd\node_modules\mongoose\lib\schema.js:677:27)
at Schema.add (C:\Users\BackEnd\node_modules\mongoose\lib\schema.js:495:12)
I am having 2 schemas, userPost.js, that I am using in userAccount.js.
What is the problem ?
Why am I getting the following error:
TypeError: Invalid schema configuration: model is not a valid type within the array posts
I tried consulting the following link especially the 3rd code excerpt of the official Mongoose's documentation:
https://mongoosejs.com/docs/schematypes.html#arrays
I changed the following code:
posts:[
{
type: userPost
}
]
To:
posts:
{
type: [userPost]
}
but still getting the same error.
I am not sure but this can be the case whenever you are referring to other model you always have to use the mongoose reference keyword and then use information from that model to create an array.
You should have your schema as follows:
const userPost = require("./UserPost");
const mongoose = require("mongoose");
let userAccountSchema = new mongoose.Schema({
id:{
type: mongoose.Types.ObjectId
},
name:{
type: String
},
posts: [userPost]
}, {timestamps: true});
let userAccount = mongoose.model("account", userAccountSchema);
module.exports = userAccount;
posts does not need a type declaration.
Two things you have to remember:
First is that because you are creating a schema and you are not changing your schema in apps, it is not recommended to use let. instead, try to store your schema in a Const variable.
The "posts" is an array, you can simply write your schema to an array and not use types. Also, you must use the schema on another schema. You can change your code with:
const mongoose = require("mongoose");
export const userPostSchema = new mongoose.Schema({
id:{
type: mongoose.Types.ObjectId
},
body:{
type: String
}
}, {timestamps: true});
const UserPost = mongoose.model("post", userPostSchema);
module.exports = UserPost;
and then:
import {userPostSchema} from "./UserPost" ;
const mongoose = require("mongoose");
const userAccountSchema = new mongoose.Schema({
id:{
type: mongoose.Types.ObjectId
},
name:{
type: String
},
posts: [userPostSchema]
}, {timestamps: true});
let userAccount = mongoose.model("account", userAccountSchema);
module.exports = userAccount;

Can't update values in mongodb database

Username doesn't get updated after running this. I also tried UpdateOne and it didn't work as well. The code was supposed to update an array but I tried updating the username to make it easier to track down the problem.
const mongoose = require('mongoose');
const schema = mongoose.Schema;
const userSchema = new schema({
Username:{
type: String,
required: true
},
Password:{
type: String,
required: true
},
Cart: Array
});
const User = mongoose.model('User', userSchema);
module.exports = User;
.
app.post('/putbox', (req, res) => {
var query = { Username: user };
var newvalues = { $push: { Cart: "Boxing" } };
try{
User.find(query).then((d)=>{
var values = d[0].Cart;
values.push("boxing")
User.findByIdAndUpdate(d._id, {Username: "test1"})
});
} catch(err) {
console.log(err);
}
res.redirect('/boxing');
});
I believe the syntax is not correct. The first element of updateOne searches for matches to update. You are just passing d._id which is not the same as the _id key in your db structure. Try this one
User.updateOne({ _id: d._id }, {Username: "test1"})

Updating mongodb document with new document id

I am trying to $push a document id to a collection but it seems to not working. I don't understand what I am doing wrong here. Please help me out.
this is how user model looks like in my codebase
const userSchema = new Schema({
first_name: String,
...
products: [{ type: Schema.Types.ObjectId, ref: 'Product' }]
});
const UserModel = model('User', userSchema);
product model
const productSchema = new Schema({
name: string,
...
user_id : [{ type: Schema.Types.ObjectId, ref: 'User' }]
});
const ProductModel = model('Product', productSchema);
controller
const savedUser = await new UserModel({ ...user }).save();
product.user_id = savedUser._id;
const savedProduct = await new ProductModel(product).save();
savedUser.update({ $push: { products: savedProduct._id } });
console.log(savedUser.populated('products')); // undefined
From the docs:
If the path was not populated, returns undefined.
You need to populate before populated can be used.

Mongoose + Mongodb User.update not working

What I am trying to do is create a new collection, and push that collection into a specific User.collections array. I have read many stackoverflow posts and they all say to use either User.update() or User.findOneAndUpdate(). I am have no luck with either. I can create a Collection and that is saved to mongo so I know I am indeed accessing the db. Here is my code, if any of you can help I would appreciate it.
User Schema
const mongoose = require('mongoose');
const { Schema } = mongoose;
const userSchema = new Schema({
googleID: String,
givenName: String,
familyName: String,
collections: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "collection"
}
]
});
mongoose.model('users', userSchema);
Collection Schema:
const mongoose = require('mongoose');
const { Schema } = mongoose;
const collectionSchema = new Schema({
type: String,
name: String,
gamesCollected: [
{
id: Number
}
]
});
mongoose.model('collection', collectionSchema);
And my route:
router.get('/get_collection', (req, res) => {
const collection = new Collection({
type: 'SNES',
name: 'First SNES Collection',
gamesCollected: [{ id: 5353 }]
}).save();
User.update({googleID: req.user.googleID}, {$push: {collections: collection}});
});
Save is not a synchronous operation but asynchronous so you need to use the promise it returns and handle it and once it is complete then update the user model. Something among these lines:
router.get('/get_collection', async (req, res) => {
let collection = new Collection({
type: 'SNES',
name: 'First SNES Collection',
gamesCollected: [{ id: 5353 }]
})
await collection.save().exec();
await User.update(
{googleID: req.user.googleID},
{$push: {collections: collection._id}}
).exec();
});

Categories

Resources