How do i use Implicit relations for update in Prisma upsert - javascript

The following code should create a new id if id is not found, if id is found it should update.
for that i have used upsert function function.
in the model (prisma) i am using https://www.prisma.io/docs/guides/database/troubleshooting-orm/help-articles/working-with-many-to-many-relations my model has an Implicit relations.
how do i use update in Implicit relations
const data = await PRISMA.ref_types.upsert({
where: { id: id },
update: {
business_name: business_name,
business_logo: business_logo,
business_type: business_type,
timezone: timezone,
location_contact_details: { update: { contact: contact, email: email, } },
location_addresses: { update: { address: address, location_id: req.body.location_id, } },
languages: { create: { languages: languages } },
ref: headerData?.ref,
},
create: {
business_name: business_name,
business_logo: business_logo,
business_type: business_type,
timezone: timezone,
location_contact_details: { create: { contact: contact, email: email, } },
location_addresses: { create: { address: address, location_id: req.body.location_id, } },
languages: { create: { languages: languages } },
ref: headerData?.ref,
},
})

Related

Push new Object inside a document array

I have this schema for my user
const userSchema = mongoose.Schema({
firstName: {
type: String,
},
notifications : [{
description: String,
status: {
type: String,
enum : ['read', 'unread'],
default: 'unread'
},
dateAdded:{
type: Date,
default: Date.now
}
}],
})
supposedly I want to find the user _id first then insert a new object inside the new notification array. and it should look like this
{
_id: ObjectId('123')
firstName: 'John Doe'
notifications:[
{
description: 'somedescription'
status: 'unread'
},
{
description: 'somedescription2'
status: 'unread'
}
]
}
How can I achieve this, assuming that the notification property is non existent in the user document first, i need to check if notification property is present else add the notification property and push the new object
User.updateOne(
{ _id: userId },
{ $push: { notifications: {description: 'new notifications'} } }
)
this code is not working for me
Use $addToSet operator to achieve that
User.updateOne(
{ _id: userId },
{ $addToSet: { notifications: {description: 'new notifications'} } }
)
If that doesn't work try to add the default value too, and then that must work
User.updateOne(
{ _id: userId },
{ $addToSet: { notifications: {description: 'new notifications',
'status': 'unread'} } }
)

How to add an object to an array of object, using addToSet, or push operators in mongodb

I have an array of reviews, I want to add a review using addToSet that will check if user is present in the array, then we do not want to add since one user can only review once.
My schema looks like this:
const sellerSchema = new mongoose.Schema({
user: {
type: mongoose.Schema.Types.ObjectId,
ref: "User",
unique: true,
},
reviews: [
{
by: {
type: mongoose.Schema.Types.ObjectId,
ref: "User",
unique: true,
},
title: {
type: String,
},
message: {
type: String,
},
rating: Number,
imagesUri: [{ String }],
timestamp: {
type: Date,
default: Date.now,
},
},
],
});
I might be doing the query wrong, but can't figure out how to add a review and check if current user has not reviewed before.
Here is the query where I add the review:
router.post("/review/:_id/", async (req, res) => {
try {
const stylist_id = mongoose.Types.ObjectId(req.params._id);
const review = {
by: req.user._id,
title: req.body.title,
message: req.body.message,
rating: parseFloat(req.body.rating),
};
if (req.body.imagesUri) {
//if there is images, we need to set it up
review.imagesUri = req.body.imagesUri;
}
await Seller.updateOne(
{ _id: seller_id },
{ $addToSet: { reviews: review } } //get the review that matches to the user_id
);
return res.status(200).send(true);
}catch(err){
res.status(502).send({
error: "Error creating a review.",
});
}
});
I'm thinking of checking for seller's id and also check that no review is by current user, but it is not working.
const userID = req.user._id;
await Seller.updateOne(
{ _id: seller_id, reviews: { $elemMatch: { by: { $ne: { userID } } } } },
{ $addToSet: { reviews: review } } //get the review that matches to the user_id
);
ANSWER:
I was able to solve the issue, in case other people have same issue. I did this:
await Seller.updateOne(
{
_id: seller_id,
"reviews.by": { $nin: [req.user.id] },
//knowing req.user._id is a mongoose.Types.ObjectId.
//You can also use [id1, id2, ...] to the array to check for other id's
},
{ $addToSet: { reviews: review } } //get the review that matches to the user_id
);
Here is the documentation for $nin operator: https://www.mongodb.com/docs/manual/reference/operator/query/nin/
You are pushing the review object inside an object.
Instead do this:
await Seller.updateOne(
{ _id: seller_id },
{ $addToSet: { reviews: review } }
);

Unable to fulfilling Stripe Connect representative requirement

im trying to create a company account via Stripe Connect. The problem is that whatever i do i always receive that there is missing representative. I'm attaching my JS code below.
Thanks in advance for the help people !
currently_due: [
"representative.address.city",
"representative.address.line1",
"representative.address.postal_code",
"representative.dob.day",
"representative.dob.month",
"representative.dob.year",
"representative.email",
"representative.first_name",
"representative.last_name",
"representative.phone",
"representative.relationship.executive",
"representative.relationship.title"
],
const account = await stripe.accounts.create({
country: payload.country,
type: 'custom',
capabilities: {
card_payments: {
requested: payload.capabilities.card_payments
},
transfers: {
requested: payload.capabilities.transfers
},
},
business_profile: payload.business_profile,
business_type: payload.business_type,
tos_acceptance: {
date: Math.round(+(new Date()) / 1000),
ip: ip
},
company: {
...payload.company,
directors_provided: true,
executives_provided: true,
owners_provided: true,
},
external_account: {
object: 'bank_account',
country: 'BG',
currency: 'BGN',
account_number: 'BG80BNBG96611020345678'
}
});
const person = await stripe.accounts.createPerson(
account.id,
{
...payload.representative
}
);
let updatedAccount = await stripe.accounts.retrieve(
account.id,
);
The person representative payload looks like this. All fields are filled according to documentation and the creation passes
representative: {
first_name: document.getElementById('representative.first_name').value,
last_name: document.getElementById('representative.last_name').value,
email: document.getElementById('representative.email').value,
phone: document.getElementById('representative.phone').value,
ssn_last_4: document.getElementById('representative.ssn_last_4').value,
dob: {
month: document.getElementById('representative.dob.month').value,
day: document.getElementById('representative.dob.day').value,
year: document.getElementById('representative.dob.year').value,
},
address: {
line1: document.getElementById('representative.address.line1').value,
postal_code: document.getElementById('representative.address.postal_code').value,
city: document.getElementById('representative.address.city').value,
state: document.getElementById('representative.address.state').value,
},
relationship: {
title: document.getElementById('representative.relationship.title').value,
executive: document.getElementById('representative.relationship.executive').value === 'true',
}
}

Populating in Mongodb Aggregating

I just asked a related question here:
Mongoose/Mongodb Aggregate - group and average multiple fields
I'm trying to use Model.aggregate() to find the average rating of all posts by date and then by some author's subdocument like country.name or gender. Having trouble with this though. I know for the first stage I just need to use $match for the date and I think I need to use $lookup to "populate" the author field but not sure how to implement this.
This works for finding an average rating for all posts by date:
Post.aggregate([
{ $group: { _id: "$date", avgRating: { $avg: '$rating' }}}
]).
then(function (res) {
console.log(res);
})
And this is basically what I want to do but it doesn't work:
Post.aggregate([
{$match: {"date": today}},
{$group: {_id: {"country": "$author.country.name"}, avgRating: {$avg: "$rating"}}}
]).then(function(res) {
console.log(res)
})
User model:
const userSchema = new Schema({
email: {
type: String,
required: true,
unique: true
},
birthday: {
type: Date,
required: true,
},
gender:{
type: String,
required: true
},
country:{
name: {
type: String,
required: true
},
flag: {
type: String,
// default: "/images/flags/US.png"
}
},
avatar: AvatarSchema,
displayName: String,
bio: String,
coverColor: {
type: String,
default: "#343a40"
},
posts: [
{
type: Schema.Types.ObjectId,
ref: "Post"
}
],
comments: [
{
type: Schema.Types.ObjectId,
ref: "Comment"
}
],
postedToday: {
type: Boolean,
default: false
},
todaysPost: {
type: String
}
})
You can populate an aggregation after you fetched the data from the MongoDB. Your `Query will look a bit like this:
modelName.aggregate([{
$unwind: ''//if Needed
}, {
$group: {
_id: {"country":"$author.country.name"},
avgRating: {
$avg: '$rating'
}
}])
.exec(function(err, transactions) {
// ERRORHANDLING
// CallsBacks
modelName.populate(columnName, {path: '_id'}, function(err, populatedModel) {
// Your populated columnName inside TaleName
});
});

How to retrieve data from collection using find() method in custom date format

my Schema
Customers.js
import mongoose from 'mongoose';
const Customers = mongoose.Schema({
CustomerID: { type: String, default: "" },
Name: { type: String, default: "" },
Email: { type: String, default: "" },
PhoneNumber: { type: String, default: "" },
Join_Date: { type: Date, default: null }
}, { collection: 'Customers' });
export default mongoose.model('Customers', Customers);
my router controller
import Customers from "./Customers";
router.post('/List_All_Customers', (req, res) => {
Customers.find().lean().exec().then((Data) => {
res.json({Data: Data});
}).catch((err) => {
console.log(err);
});
})
My Current Result
{
Data: [
{
CustomerID: "6ad050d4-04ac-41f2-8c93-49f68f106889",
Name: "Uday Kumar",
Email: "uday#blaabla.com",
PhoneNumber: "+91-991010191",
Join_Date: "2018-04-24T12:00:00.000Z"
},
{
CustomerID: "792b67f9-9026-43bc-9017-46cd2568b4e9",
Name: "Prem Kumar",
Email: "prem#blaabla.com",
PhoneNumber: "+91-881010091",
Join_Date: "2018-04-24T15:00:00.000Z"
}
]
}
Expecting Result
{
Data: [
{
CustomerID: "6ad050d4-04ac-41f2-8c93-49f68f106889",
Name: "Uday Kumar",
Email: "uday#blaabla.com",
PhoneNumber: "+91-991010191",
Join_Date: "Apr-24 2018, 12:00:00"
},
{
CustomerID: "792b67f9-9026-43bc-9017-46cd2568b4e9",
Name: "Prem Kumar",
Email: "prem#blaabla.com",
PhoneNumber: "+91-881010091",
Join_Date: "Apr-24 2018, 15:00:00"
}
]
}
Is there anyway in mongodb for result in custom dates. I am using mongoose mongodb connection in my project.
I can manipulate data using for loop with momentjs but it is taking time.
So i need one solution for my question.
Thanks in advance.
Comments are appreciated.
You Can use javascript map function
like
import Customers from "./Customers";
router.post('/List_All_Customers', (req, res) => {
Customers.find().lean().exec().then((Data) => {
Promise.resolve(arr.map(item=>{
item.Join_Date = fnToConvertDateToYourFormate(item.Join_Date);
return item;
})).then(Data=>{
res.json({Data: Data});
});
}).catch((err) => {
console.log(err);
});
})
OR
You Can Use Mongoose MapReduce
http://mongoosejs.com/docs/api.html#mapreduce_mapReduce
var o = {};
o.map = function () {
this.Join_Date = fnToConvertDateToYourFormate(this.Join_Date);
emit(this.CustomerId,this)
}
o.reduce = function (k, vals) { }
mongoose.model('Customers').mapReduce(o, function (err, results) {
console.log(results)
});
You can use aggregate query. An example for this query is given below:-
db.customers.aggregate([
{$project:
{yearMonthDayUTC:
{$dateToString:
{format: "%Y-%m-%d",
date: "$date"
}
},
}
}
])
For this query, the date should be in ISO. So, while inserting element into the db, you can use new Date() as this returns the current date as a Date object. The mongo shell wraps the Date object with the ISODate helper.
An example for inserting data in db is given below:-
db.sales.insert({ "_id" : 4, "item" : "mansi", "price" : 10, "quantity" : 2, "date" : new Date(Date.now()) })
You can try mongoDB $dateToString aggregation.
Customers.aggregate([
{
$project: {
"other_field": 1, // and so on as many fields you need
Join_Date: {
{ $dateToString: { format: "%Y-%m-%d", date: "$Join_Date" } }
}
}
}
]).then((Data) => {
res.json({Data: Data});
}).catch((err) => {
console.log(err);
});
Read more about it at: https://docs.mongodb.com/manual/reference/operator/aggregation/dateToString/

Categories

Resources