mongoose aggregate model based on filter - javascript

I have a model of Review which has the field product and rating
I would like to find the sum of all ratings of a specified product and find the average by dividing by 5.
const mongoose = require('mongoose');
const ReviewSchema = mongoose.Schema({
product: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Product',
required: true,
},
rating: {
type: Number,
required: true,
},
});
module.exports = mongoose.model('Review', ReviewSchema);
how would I aggregate through all ratings and filter by product to find the sum?

I'm assuming your using nodejs , here is how I would go about doing this
const ReviewsModel = require('../Models/Review')
router.get('/average',async (req,res)=>{
try {
const reviewsPromise = await ReviewsModel.find({}).populate('product')
if(reviewsPromise[0] == undefined) throw new Error('no reviews')
const reviewsOfSpecifiedProduct= reviewsPromise.filter(rev=> rev.product.id == specifiedProductId)
const sumOfRatings = reviewsOfSpecifiedProduct
.map(rev=>rev.rating)//map to list of only ratings
.reduce((a, b)=> a + b , 0)
const ratingsAverage = sumOfRatings / 5
res.json(ratingsAverage)
} catch (error) {
console.log(error)
//handle the errors here
}
})

Related

save an array of objects to MongoDB with Mongoose on Javascript

I have this data (json):
var unique =
[
{"name":"John", "number":"4132321234"},
{"name":"Jack", "number":"451232421234"},
{"name":"Maddy", "number":"12314124"},
{"name":"Alex", "number":"213468316"}
]
What I want to do, is save this data to my mongoDB collection, with the following schema (using mongoose):
const mongoose = require('mongoose')
const Schema = mongoose.Schema
const nameSchema = new Schema({
name: {
type: String,
required: true,
},
number: {
type: String,
required: true,
},
});
const Name_db = mongoose.model('Name_db', nameSchema)
module.exports = Name_db;
I wrote a loop, to attempt to do this:
for (var k = 1; k < unique.length; k++) {
var name_mongo = new Name_db({
name: unique[k].name,
number: unique[k].number,
},
)
console.log(unique[k].name)
} name_mongo.save()
.then(results => {
res.send(results)
})
.catch(err => {
console.log(err);})
This doesn't work because right now it is only sending data once to mongo DB, meaning only of the arrays is actually being sent over, instead of all 3 of them being sent to mongoDB.
Would appreciate any help, thank you for the time.
Name_db.insertMany(unique)
.then((result) => console.log("Inserted", result))
.catch((error) console.log(error));
or
const result = await Name_db.insertMany(unique); // remember to decorate the function async

MongoDB only using one entry - Discord.js

Currently I have a command of which checks someone else's balance with my sort of economy system. The issue is that it's only storing one users data - so when the database is empty and the bot goes to create a profile for a user that is the only profile ever created - for example when another member goes to check their balance then it won't show their own profile but it shows only the first person to create a profile's balance. I've tried everything - nothing works. Please help... Below is the command to check balance, my schema and the profile creating function.
if (message.author.bot) return;
let member = message.mentions.members.first();
if (member) {
if (message.content.match('!ponyo balance') && profileSchema.findOne({ memberId: member.id, guildId: member.guild.id })) {
console.log('trying to execute balance.createBalance() with the user id: ' + member.id)
const profileBalance = await balance.createBalance(member);
console.log(`profileBalance: ${profileBalance}`)
await message.reply(`${message.mentions.members.first()} has ${profileBalance.coins} coins! :D`);
}
}
})
const Balance = require('./profileSchema')
const mongoose = require('mongoose')
//create profile thingy
async function createBalance(member) {
if (Balance.findOne({ memberId: member.id })) {
let balanceProfile = await Balance.findOne({ memberId: member.id })
if (balanceProfile) {
return balanceProfile;
} else {
balanceProfile = await new Balance({
userID: member.id,
serverID: member.guild.id
});
await balanceProfile.save().catch(err => console.log(err));
console.log("returning: " + balanceProfile.toString());
return balanceProfile;
}}}
module.exports = { createBalance };
const mongoose = require('mongoose');
const profileSchema = new mongoose.Schema({
userID: { type: String, require: true, unique: true},
serverID: { type: String, require: true },
coins: { type: Number, default: 100 },
bank: { type: Number }
})
const model = mongoose.model('ProfileModels', profileSchema);
module.exports = model;
There is no memberId in your profile Schema..
if (Balance.findOne({ memberId: member.id })) {
Maybe you are mistakenly put memberId instead of userId or
you have Separate Balance Scheme.. which is not imported Correctly..

Mongoose update update nested object inside an array

I'm trying to query and update an element in the rosters array ( roster.schedule.monday.start) & then update the value in this example.
monday.start these two keys need to be dynamic
I think the approach would be something like this
Find document by _id
find matching object in array by _id
update nested values
I have tried this below with no luck, could anybody assist in this problem
many thanks
// Mongoose query
exports.updateRoster = (req, res) => {
const editDay = req.body.day;
const value = req.body.valueOfEntry;
const userId = req.body.id;
const rosterId = req.body.rosterId;
const startPerieod = req.body.time;
let dynObj = {
["rosters.$.schedule.$." + editDay + ".$." + startPerieod]: value,
};
Carer.updateOne({ "rosters._id": rosterId }, { $set: dynObj }).exec(
(err, roster) => {
if (err) {
return res.status(400).json({
error: err,
});
}
res.json(roster);
}
);
};
// Schema
const mongoose = require("mongoose");
const { ObjectId } = mongoose.Schema;
const carersSchema = new mongoose.Schema({
rosters: [
{
schedule: {
monday: {
start: { type: String },
finish: { type: String },
notes: { type: String },
},
],
});
module.exports = mongoose.model("Carers", carersSchema);
Try using $set and array filters like in the link
Carer.findOneAndUpdate({_id: carerId},
{
"$set": {[`rosters.$[outer].schedule.${editDay}.${startPerieod}`]: value}
},
{
"arrayFilters": [{ "outer._id": roasterId }]
},
function(err, response) {
if(err) console.log(err)
console.log(response)
})

mongoose find returning empty array even their is a value on the database

I'm trying to add commodity data to my stockrecord collection and if the commodity name is already in the stockrecord collection I just want to add the quantity of the commodity quantity to my stockrecord quantity.
but even their is existing data the, find method is returning an empty array
This my code
commodity.map(async (e) => {
const data = await new Commodity({
name: e.commodityName,
units: e.units,
quantity: e.quantity,
});
data.donator = donator;
await data.save();
const stock = await StockRecord.find({
name: {
$eq: e.commodityName,
},
});
//console.log(stock);
if (stock.length === 0) {
const record = await new StockRecord({
name: e.commodityName,
units: e.units,
quantity: parseFloat(e.quantity),
});
await record.save();
console.log(record);
} else {
console.log('may sulud');
stock[0].quantity += parseFloat(e.quantity);
await stock[0].save();
}
});
This is my stockrecord model
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const stockRecordSchema = new Schema({
name: {
type: String,
},
units: {
type: String,
enum: \['kg', 'pcs'\],
},
quantity: {
type: Number,
},
});
Array.map does not accept Promises
Try using for (const item of commodity) { //async magic here }

Why is this mongoose 'findOne' query always returning null?

I am trying to find a specific document with mongoose in my Cosmosdb with this query described below.
const mongoose = require('mongoose');
var ObjectID = require('mongodb').ObjectID
const keys = require('../config/keys');
const Item = mongoose.model('items');
const uploadToBlob = async (containerName, blobName, json, id) => {
console.log('id', id)
Item.findOne({ _id: id }, (foundItem) => {
console.log(foundItem)
});
console.log('here')
Item.findOneAndDelete({ name: blobName });
};
I am successfully able to find the document when querying like this below.
const scanMongo = () => {
Item.find({
_id: {
$gt: ObjectID.createFromTime(Date.now() / keys.mongoPurgeInterval)
}}, (err, foundItems) => {
if(err) {
console.log("Oops", err);
return;
}
foundItems.forEach(item => {
JSON.stringify(item)
const blobName = item.name;
json = "'"+item+"'"
const id = item._id
uploadToBlob(keys.containerName, blobName, json, id);
});
});
}
This is what the object I'm looking for looks like when pulled from the query above.
[ { _id: 5cabd5c6e16288230cba2cf6, name: 'test', value: 1, __v: 0 } ]
For kicks, here my model.
const mongoose = require('mongoose');
const { Schema } = mongoose;
const itemSchema = new Schema({
name: String,
value: Number,
});
mongoose.model('items', itemSchema);
I'm befuddled. Any help would be bawler. Thanks!!!
Yeah, the first parameter is supposed to catch the error.
Item.findOne({ _id: id }, (error, foundItem) => {
console.log(foundItem)

Categories

Resources