Mongoose querying an array of objects - javascript

How to querying an array using Mongoose ?
search Schema:
const searchschema = new schema({
yeardate: { type: Number, required: true, min: 1820 },
word: { type: String, required: true, index: true },
user: [{ type: schema.Types.ObjectId, ref: 'User' }] })
user Schema:
const userschema = new schema({
username: { type: String, required: true, unique: true, index: true },//
name: { type: String, default: 'NoName' },
gender: { type: String, default: 'male' }, })
This is the query I have tried but did not work:
searchmodel.paginate({ 'user': { $elemMatch: { gender: 'female' } } }, { page: page, limit: 5, populate: ['user'] }).then(searches => {
if (!searches) {
return res.json({ message: 'there is no search' })
}else {
return res.json(searches)
}
})

Related

Can't filter by a nested populated item

I'm using mongoose-paginate-v2 for my TransactionModel.
I can't seem to filter by the user name or email.
If I don't use any query the docs return with the populated objects, like the user's name, and email, so I believe the issue is with the filter variable.
I want to keep using mongoose-paginate-v2
const transactionSchema: Schema = new Schema(
{
user: { type: Types.ObjectId, ref: CollectionNames.user, required: false },
subscription: { type: Types.ObjectId, ref: CollectionNames.subscription, required: false },
paidAt: { type: Date, required: true, default: new Date() },
amount: { type: Number, required: true },
currency: { type: String, required: true, default: CurrencyCodes.USD },
status: { type: String, required: true, default: TransactionStatuses.pending },
refundedAt: { type: Date, required: false },
refundAmount: { type: Number, required: false },
provider: { type: String, required: true },
providerTransactionId: { type: String, required: true },
invoiceLink: { type: String, required: false },
referral: { type: referralSchema, required: false },
eventsHistory: { type: [String], required: false, default: [] }
},
{
timestamps: true
}
);
// The function body:
const { page, limit, query: searchQuery } = query;
const options = {
page: page || 1,
limit: limit || 10,
sort: {
createdAt: -1
},
populate: [
{
path: 'user',
select: 'name socialAccounts email lastLoginEmail notificationEmail'
},
{
path: 'referral',
select: 'user commission payoutExpectedAt paidAt status'
}
],
lean: true
};
const filter = {};
if (searchQuery) {
const searchQueryRegex = new RegExp(searchQuery, 'i');
Object.assign(filter, {
$or: [
{
providerTransactionId: {
$regex: searchQueryRegex
}
},
{
'user.name': {
$regex: searchQueryRegex
}
},
{
'user.email': {
$regex: searchQueryRegex
}
},
]
});
}
const { docs, totalDocs, totalPages, hasNextPage } = await TransactionModel.paginate(filter, options);

how can obtain a reverse populate in two models of mongosee

hi i have this mongose models
new mongoose.Schema({
type_order: {
type: String,
required: true,
},
article: {
required: true,
type: [{
id: {type: mongoose.Schema.Types.ObjectId, ref: 'product'},
type_article: String,
quanty: Number,
}],
},
status: {
required: true,
type: String,
},
profile_id: {
required: true,
type: mongoose.Schema.Types.ObjectId,
ref: 'customer',
},
}, {timestamps: true});
module.exports = mongoose.model('order', dataSchema);
const dataSchema = new mongoose.Schema({
profile_id: {
type: String,
required: true,
},
title_lower: {
required: true,
type: String,
},
title: {
required: true,
type: String,
},
category_id: {
required: true,
type: String,
},
status: {
required: true,
type: String,
},
brand: {
required: true,
type: String,
},
description: {
required: true,
type: String,
},
stock: {
required: true,
type: Number,
},
price: {
required: true,
type: Number,
},
discount: {
required: true,
type: Number,
},
images: {
type: [{
url: String,
first: Boolean,
}],
},
}, {timestamps: true});
module.exports = mongoose.model('product', dataSchema);
I am trying to obtain the orders that have in their article field an article or several that belong to the profile id of the product that would be the person who published that product.
I am currently doing it bringing all the orders for the person's products but I know that it is not the most optimal way to do it and in the long run the performance will be affected.
i am trying something like this:
const profile = await customer.findOne({userId: req.user.id});
if (profile) {
// eslint-disable-next-line max-len
const articles = await Product.find({profile_id: profile._id});
const response=[];
const preresponse=[];
for (let index = 0; index < articles.length; index++) {
const element = articles[index];
const orders= await getOrdersByArticleId(element._id, res);
preresponse.push({
'article_id': element._id,
'title': element.title,
'price': element.price,
'stock': element.stock,
orders,
});
articles[index].orders = orders;
}
preresponse.forEach((art)=> {
art.orders.forEach((order)=>{
console.log(order);
const result = response.find(({order_id}) => order_id == order.order_id); ;
console.log(result);
if (result) {
console.log('holaa');
} else {
response.push({
'order_id': order.order_id,
'type': order.type_order,
'status': order.status,
'date': order.date.toDateString(),
'articles': [{'product_id': order.article_id,
'quanty': order.quanty}],
});
}
});
});
return res.status(200).json(articles);
}

Looping Over And Array of Objects and Updating Each One

I'm trying to update objects inside an array based on specific conditions that I check using two functions. I couldn't achieve this with the match feature available in mongoose.
As you can see below, I'm trying to loop over the array of posts, send each post and check if it fulfills a condition, then update it using findOneAndUpdate. The functions isLessThanOne and isAchieved return the expected value.
(async () => {
let posts = await Post.find()
posts.map(async (post) => {
if (isLessThanOneDay(post.deadline)) {
console.log(post.id, post._id)
await Post.findOneAndUpdate(post.id, { $set: { category: 'deadline' }})
} else if (isAchieved(post.milestones)) {
await Post.findOneAndUpdate(post.id, { $set: { category: 'achieved' }})
} else {
await Post.findOneAndUpdate(post.id, { $set: { category: 'newGoals' }})
}
})
})()
This is the schema
const { type } = require("express/lib/response")
const mongoose = require("mongoose")
const PostSchema = new mongoose.Schema({
// we have to link or refer each post to a user
user: {
type: mongoose.Schema.Types.ObjectId,
ref: "user",
},
title: {
type: String,
required: true
},
desc: {
type: String
},
milestones: [],
likes: [
{
user: {
type: mongoose.Schema.Types.ObjectId,
ref: "user"
},
fName: {
type: String,
required: true
},
date: {
type: String,
required: true
}
}
],
comments: [
{
user: {
type: mongoose.Schema.Types.ObjectId,
ref: "user"
},
text: {
type: String,
required: true
},
fName: {
type: String,
},
date: {
type: String,
}
}
],
rewards: [
{
user: {
type: mongoose.Schema.Types.ObjectId,
ref: "user"
},
fName: {
type: String,
required: true
},
date: {
type: String,
required: true
},
reward: {
type: String,
required: true
},
price: {
type: Number,
required: true
}
}
],
date: {
type: String,
required: true
},
shares: [
{
user: {
type: mongoose.Schema.Types.ObjectId,
ref: "user"
},
fName: {
type: String,
required: true
},
date: {
type: String,
required: true
}
}
],
deadline: {
type: String,
required: true
},
category: {
type: String,
}
})
module.exports = Post = mongoose.model('post', PostSchema)
The problem is that I couldn't update the posts and I've already tried using udpate, directly updating it with post.category then save. Any help would appreciated.
Try this:
(async () => {
let posts = await Post.find()
posts.map(async (post) => {
if (isLessThanOneDay(post.deadline)) {
console.log(post.id, post._id)
await Post.findOneAndUpdate({ _id: post.id }, { $set: { category: 'deadline' }})
} else if (isAchieved(post.milestones)) {
await Post.findOneAndUpdate({ _id: post.id }, { $set: { category: 'achieved' }})
} else {
await Post.findOneAndUpdate({ _id: post.id }, { $set: { category: 'newGoals' }})
}
})
})()
If I recall, the filter parameter must be an object.

i want to check if current user is following other user

i want to check if current user is following other use lets say check if user A is following user B.
User Model:-
const UserSchema = new Schema({
email: {
required: true,
type: String,
unique: true,
lowercase: true,
validate: (value) => {
if (!validator.isEmail(value)) {
throw new Error('Invalid email address.');
}
}
},
fullName: {
required: true,
type: String,
},
username: {
required: true,
type: String,
unique: true,
lowercase: true,
minlength: 3,
},
password: {
type: String,
minlength: 8,
},
avatar: String,
bio: {
type: String,
default: null,
maxlength:300,
},
location: {
type: String,
default: 'Bangalore'
},
website: {
type: String,
default: null,
},
joindate: {
type: Date,
default: new Date()
},
isVerified:{
type:Boolean,
default:false,
}
})
const UserModel = mongoose.model('User', UserSchema);
module.exports = UserModel;
Followings Model:-
const FollowingsSchema = new Schema({
user: {
ref: 'User',
unique:true,
type: Schema.Types.ObjectId,
},
followings: [{
user: {
type: Schema.Types.ObjectId,
ref: 'User'
}
}]
})
const Followings = mongoose.model('Followings', FollowingsSchema);
module.exports = Followings;
Followers Model:-
const FollowersSchema = new Schema({
user: {
ref: 'User',
unique:true,
type: Schema.Types.ObjectId,
},
followers: [{
user: {
type: Schema.Types.ObjectId,
ref: 'User'
}
}]
})
const Followers = mongoose.model('Followers', FollowersSchema);
module.exports = Followers;
currently i was able to achieve this by iterating through each follower and check if user exist in that user followers list.
i want to achieve this with mongodb aggregation ,im new to mongob

findByIdAndUpdate keeps being caught in .catch

So when I am executing my findByIdAndUpdate it doesn't execute my promise as expected and goes into my catch. I sent responses to postman and using res.json(req.user.id) and res.json(profileFields) . This is the response I get when I use
profileFields
{
"user": "5b3134a0e2543b06d130a5d7",
"handle": "wadeaston1",
"status": "Developer",
"skills": [
"HTML",
" CSS",
" Javascipt"
],
"social": {}
}
i'm at a loss here because all my fields are passing in the values as expected into user and $set. I don't understand why its going to my catch
Profile.findByIdAndUpdate(
{ user: req.user.id },
{ $set: profileFields },
{ new: true }
)
.then(profile => res.json(profile))
.catch(err => {
res.json("Timeout");
console.log("HI");
});
Here is my Profile Schema
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
//Create Scheme
const ProfileSchema = new Schema({
user: {
//this will associate user by their ID
type: Schema.Types.ObjectId,
ref: "users"
},
handle: {
type: String,
required: true,
max: 40
},
company: {
type: String
},
website: {
type: String
},
location: {
type: String
},
status: {
type: String,
required: true
},
skills: {
//Array of strings
type: [String],
required: true
},
bio: {
type: String
},
githubusername: {
type: String
},
experience: [
{
title: {
type: String,
required: true
},
company: {
type: String,
required: true
},
location: {
type: String
},
from: {
type: Date,
required: true
},
to: {
type: Date,
required: true
},
current: {
type: Boolean,
default: false
},
description: {
type: String
}
}
],
education: [
{
school: {
type: String,
required: true
},
degree: {
type: String,
required: true
},
fieldofstudy: {
type: String,
required: true
},
from: {
type: Date,
required: true
},
to: {
type: Date,
required: true
},
current: {
type: Boolean,
default: false
},
description: {
type: String
}
}
],
social: {
youtube: {
type: String
},
twitter: {
type: String
},
facebook: {
type: String
},
linkedin: {
type: String
},
instagram: {
type: String
}
},
date: {
type: Date,
default: Date.now
}
});
module.exports = Profile = mongoose.model("profile", ProfileSchema);
findByIdAndUpdate is for finding the document to update by its _id value, but you need to find the document by its user field, so you should be using findOneAndUpdate instead:
Profile.findOneAndUpdate(
{ user: req.user.id },
{ $set: profileFields },
{ new: true }
)
.then(...
No need to manually cast req.user.id to an ObjectId as Mongoose will do that for you based on the way user is defined in your schema.
Based on the error you gave, it looks like you need to turn req.user.id from a string to an ObjectId:
Profile.findByIdAndUpdate(
{ user: new mongoose.Types.ObjectId(req.user.id) },
{ $set: profileFields },
{ new: true }
).then( /* rest of code */
This assumes you did a const mongoose = require('mongoose') or similar.

Categories