when fetching a document from the database, I want to destructure fields from it in one line, other ORMs such as TypeORM offer this ability out of the box, but I couldn't manage to do the same with Mongoose.
example:
// working TypeORM example
const { id, name, email } = await this.userRepository.findOne({ handle: 'JohnDoe' });
// the above line is achieved with mongoose with 2 additional steps:
const doc = await this.userModel.findOne({ handle: 'JohnDoe' });
const { id } = doc;
const { name, email } = doc.toObject();
How to improve the mongoose example above, thanks!
Related
I have a function that create guild entry for DiscordJS, but when the script start and also if the function is called multiple times, it create around 400 duplicate documents, it create by ID and the ID is unique, so it's not normal
My schema structure only have a ID type String and unique is true
client.createGuild = async guild => {
const exist = await Guild.findOne({ id: guild.id });
if(!exist) {
await Guild.create({ id: guild.id }); // new Guild().save() keep duplicate too
}
}
It look like the if statement doesn't exist
const Schema = mongoose.Schema;
const FooSchema = new Schema({
id: { type: String, index: true, unique: true }
});
const Foo = mongoose.model('Foo', FooSchema);
Foo.createIndexes();
If collection already exists. Create index manually to the collection via atlas or cmd.
You can combine getData and createData functions to one. Here is the example:
const mongoose = require('mongoose');
async function getData(Guild, guild) {
if (!mongoose.connection.readyState) await mongoose.connect('MONGO_URL'); // In case you haven't connect to database
const data = await Guild.findOne({ id: guild.id }); // get data from database
if (!data) {
return new Guild({
id: guild.id,
}); // If no data exists for the guild, return new model
}
return data; // If the data already exists, return that
}
Now if you want to get data from mongodb you just call the function. It automatically create and save a new one if there is not.
Comment if you still have any problem or you have got what you need.
Make sure to call the function with await or it won't return the data.
How can i do this?
I have a data stucture for each user in a user collection, I have created my own schema for the user object stored in the collection.
I want to have a favoriteMovies collection initalised into this object so that i can add movie objects inside.
Heres an example of what im trying to do :
async function signUp(email, password){
const {user} = await auth.createUserWithEmailAndPassword(email, password)
// initialise the schema for the data
const userInitialised = await db.collection('users').doc(user.uid).set(userSchemaObject(user.uid))
return userInitialised;
}
Then the schema so far:
export default function userSchemaObject(uuid){
return {
uuid,
favmovies:[]
}
}
I'm asking how to push data to a nested array
From your question and comment, your favmovies field should be of type Array and does not seem to be "nested". Therefore you should simply use arrayUnion() in order to push data to this Array.
The following code demonstrates how to create a doc with an empty Array field, then, later, how to push a value.
const db = firebase.firestore();
const newDocRef = db.collection('test').doc();
newDocRef
.set({
uuid: 'uuid_value',
favmovies: [],
})
.then(() => {
newDocRef.update({
favmovies: firebase.firestore.FieldValue.arrayUnion('movie1'),
});
});
Note that you can pass several elements to the arrayUnion() method.
newDocRef.update({
favmovies: firebase.firestore.FieldValue.arrayUnion(
'movie1',
'movie2'
),
});
I am working with Graphql and then I come to a situation where I need to populate, but I am not getting how to excute that.
Here is my Booking schema
const mongoose=require('mongoose')
const Schema=mongoose.Schema
const bookingschema=new Schema({
event:{
type:Schema.Types.ObjectId,
ref:'Event'
},
user:{
type:Schema.Types.ObjectId,
ref:'User'
}
}
,{timestamps:true})
module.exports=mongoose.model('Booking',bookingschema)
Here is my resolver to create a booking event
bookevent: async args => {
const fetchevent = await Event.findOne({ _id: args.eventid });
const booking = new Booking({
user: "5d64354bfd7bb826a9331948",
event: fetchevent
});
const result = await booking.save();
return {
...result._doc,
_id: result._id,
createdAt: new Date(result._doc.createdAt).toISOString(),
updatedAt: new Date(result._doc.updatedAt).toISOString()
};
}
};
When i try to run the graphql query i easily get what i require
mutation{
bookevent(eventid:"5d6465b4ef2a79384654a5f9"){
_id
}
}
gives me
{
"data": {
"bookevent": {
"_id": "5d64672440b5f9387e8f7b8f"
}
}
but now how do I populate user here ???
cause at the end I want this query to be executed successfully
mutation{
bookevent(eventid:"5d6465b4ef2a79384654a5f9"){
_id
user{
email
}
}
Schema of eventtype is
type Event{
_id:ID!
title:String!
description:String!
price:Float!
date:String!
creator:User!
}
cause my user schema has email inside it and I am trying to reach that out
So where in my Booking resolver should I populate "user" ??
To resolve the user I did
const result = await booking.save();
const res=await result.populate("user");
console.log(res) //doesnt gives the populated user only gives me id
If I am not wrong for these cases populate is the way right?
I hope it may help you.
const result = await booking.save();
const res=await booking.findById(result._id).populate("user");
console.log(res)
I have never made anything like this before but after saving new Booking here:
const result = await booking.save();
You can use .populate() on result. Example:
await result.populate("user");
Or if the above not work:
await result.populate("user").execPopulate();
I am working on billing in node.js and I created a new Model Stripecustomer where I save the stripe customer id and this customer's email. I kinda copied the main code form my other mongoose models and changed it. I had hoped to instantly start using it but when I tried to find a document in this model I got the following error:
⛔️ Error:
TypeError: Cannot read property 'findOne' of undefined
I have looked at it for half an hour and I can't see what I did wrong. Can anyone tell me where I did something wrong?
workspace.controller.js: here is where I try to create a subscription. Stripecustomer is undefined, but I don't get why since I imported it on top
const stripe = require("stripe")("sk_test_dvebbZQPA4Vk8kKZaEuN32sD");
const {
Group, User, Workspace, Stripecustomer
} = require('../models');
const { sendErr } = require('../../utils');
const billing = async (req, res) => {
try {
const email = 'tijl.declerck#outlook.com';
// get the payment plan
const plan = await stripe.plans.retrieve('plan_EK1uRUJLJcDS6e');
// get the stripe customer or create a new one
let customer;
const existingCustomerDoc = await Stripecustomer.findOne({ email: email });
// if we couldn't find an existing customer in our database...
if (!existingCustomerDoc[0]) {
// then we create a new customer
customer = await stripe.customers.create({
email,
source: 'src_18eYalAHEMiOZZp1l9ZTjSU0'
});
} else {
// we retrieve this customer in stripe
customer = await stripe.customers.retrieve(existingCustomerDoc.customer_id);
}
// subscribe the customer to the plan
// You now have a customer subscribed to a plan.
// Behind the scenes, Stripe creates an invoice for every billing cycle.
// The invoice outlines what the customer owes, reflects when they will be or were charged, and tracks the payment status.
// You can even add additional items to an invoice to factor in one-off charges like setup fees.
const subscription = await stripe.subscriptions.create({
customer: customer.id,
items: [{ plan: plan.id }]
});
res.status(200).json({
message: 'payment complete',
obj: subscription
});
} catch (err) {
return sendErr(res, err);
}
};
stripecustomer.model.js
const mongoose = require('mongoose');
const { Schema } = mongoose;
const stripeCustomerSchema = new Schema({
email: {
type: String,
required: true
},
customer_id: {
type: String,
required: true
}
});
const Stripecustomer = mongoose.model('Stripecustomer', stripeCustomerSchema);
module.exports = Stripecustomer;
The error is probably coming from ur models index.js file, can u share ur models/index.js file to make this more clear, because findOne is a mongoose function, if u get undefined it means Stripecustome is not an instance of a mongoose model
How can I execute the following queries together in a single javascript function for mongoDB?
//find the reviews from the reviews collection
var proRev = db.reviews.find({productID: "123"}).toArray();
//update the products collection
db.products.update({productID : "123"},{$push:{Reviews:proRev}},{multi:true});
//remove the reviews from the reviews collection
db.reviews.remove({productID: "123"});
The function would be based on finding the reviews for productID "123" from a reviews collection, and inserting them as an array, in a new field for productID "123" found in the products collection.
Rather than executing the queries seperate, I would like them to execute in a single function - I'm a javascript noob so sorry if this is a stupid question.
Thanks
Use promises.
Example:
const MongoClient = require('mongodb').MongoClient;
const url = 'mongodb://localhost:27017';
const dbName = 'myproject';
(async function() {
let client;
try {
client = await MongoClient.connect(url);
console.log("Connected correctly to server");
const db = client.db(dbName);
const [res1, res2] = await Promise.all([
db.collection('inserts').findOne({
foo: "bar"
}),
db.collection('inserts').findOne({
bar: "foo"
})
]);
} catch (err) {
console.log(err.stack);
}
// Close connection
client.close();
})();
If you want to do it in one operation within MongoDB, try using findOneAndUpdate