How can I get the value of this array in MongoDB? - javascript

How can I get the value of this array
const { model, Schema} = require("mongoose")
let ticketSchema = new Schema({
GuildID : String,
MembersID: [String],
TicketID: String,
ChannelID: String,
Closed: Boolean,
Locked: Boolean,
Type: String,
Claimed: Boolean,
ClaimedBy: String,
Open:Boolean,
OpenBy:String,
})
module.exports = model("Ticket", ticketSchema);
Example:
{
_id: new ObjectId("63d8340e0a415466f7ad55f0"),
GuildID: '1066373193767592047',
MembersID:
[0]:811664013313310720
TicketID: '2',
ChannelID: '1069728239200780398',
Closed: false,
Locked: false,
Type: 'Hola',
Claimed: false,
Open: false,
OpenBy: '811664013313310720',
__v: 0
}
How can I get the value of MembersID:[0]:811664013313310720 in this case it would be 811664013313310720 I need it to check on a system
Try methods with findOne, Find

I assume you use MongoDB Driver and the following syntax can extract the property MembersID
data = await dbo.collection(COLLECTION).find({},{projection:MembersID:1}).toArray()
MongoDB Drivers → Node.js
const MongoClient = require('mongodb').MongoClient;
const config = require('../config/mongodb'); // Your Own Connections Details
let db, dbo;
const COLLECTION = 'Ticket';
db = await MongoClient.connect(config.url, config.connection);
dbo = await db.db(config.database);
let data = [];
const options = {
projection: { MembersID: 1 }
};
data = await dbo.collection(COLLECTION).find({}, options).toArray();
data[0].MembersID // Access the Array
Mongoose
data = await dbo.collection('Ticket').find({}).exec();
Point to Note
The MembersID is a type of Integer, ensure you have right type when comparing
The MongoDB client connection details is omitted. MongoDB Connect to DB Official Document
Mongoose Refer to this document Mongoose find

Related

unable to push object returned from mongoose query

I am making a social media backend.
I save post added by the used in a Post model and user data in a User model.
GITHUB_REPO_LINK_AT_END
NOTE: UserSchema have a Schema.TypesOf.ObjectId Reference To POST Model. User_Model_&_Post_Model_are_provided_in_the_end
To get all posts of a particular user, I make a GET request to the route "/post" with body:
{ "id" : "6399d54c00308a2fe0bdf9fc"} //sending user id to fetct all the ID of the post from USER model, so i can then query the POST model for the posts
This the function I am getting problem with:
const getPost = async(req, res)=>{
if(req.body.id){
try {
const user = await User.findById(req.body.id).select('-_id post');
//THIS IS THE PART I NEED HELP WITH-------------------------------------------
const posts = await user.post.map(async(postID) => {
const result = await Post.findById(postID).select('-_id title body');
//console.log(result) THIS PRINTS THE CORRECT OBJ FROM DB
return result; //THIS RETURNS AN EMPTY OBJECT HERE
});
//----------------------------------------------------------------------------
res.status(200).json(posts);
} catch (error) {
console.log(error);
res.status(500).json({message: error.message});
}
}
};
when sending a GET request it returns an empty array with empty objects.//PS: no. of empty obj = actual no. of obj in DB
//This is the response
[{},{},{},{},{},{},{},{},{},{},{}]
{
//This is the user object
"_id": "6399d54c00308a2fe0bdf9fc",
"createdAt": "2022-12-14T13:52:40.483Z",
"name": "ShivamUttam",
"username": "Fadedrifleman",
"post": [
"6399d57200308a2fe0bdfa00",
"6399d5c400308a2fe0bdfa06",
"6399d5ca00308a2fe0bdfa0a",
"6399d5d600308a2fe0bdfa0e",
"6399de29e8aa8697299941c5",
"6399dec6e9b79ac66c59cd7a",
"6399df0dbea937f8b3365979",
"6399df31bea937f8b336597d",
"6399df31bea937f8b3365981",
"6399df32bea937f8b3365985",
"6399df33bea937f8b3365989"
],
"__v": 5
}
Model for USER and POST:
User:
const mongoose = require('mongoose');
const userSchema = new mongoose.Schema({
createdAt: {
type: Date,
default: Date.now()
},
name: {
type: String,
required: [true, 'name must be provided'],
},
username : {
type: String,
required: [true, 'Username must be provided'],
},
post:[{
type: mongoose.Schema.Types.ObjectId,
ref: 'Post',
}],
});
module.exports = mongoose.model('User', userSchema)
Post:
const mongoose = require('mongoose')
const postSchema = new mongoose.Schema({
createdAt: {
type: Date,
default: Date.now()
},
title:{
type: String,
required: [true, "title cannot be empty"],
max: [20, "title cannot exceed 20 character"]
},
body: {
type: String,
max: [145, "body cannot exceed 145 character"],
},
tags:{
type: String,
},
});
module.exports = mongoose.model('Post', postSchema);
https://github.com/Fadedrifleman/socialMediaAppBackend/tree/master
Since you have used async callback function in the map method, a async function always return a promise, whatever the entity is returned by the function is wrapped inside a promise and that promise is returned.
If you want to use map function with async js code, you can try the following
const posts = await Promise.all(user.post.map(async(id)=>{
const result = await Post.findById(postID).select('-_id title body');
return result;
}));
and if you want to straightaway send the posts, you can also use .lean() method on posts, as in
await Post.findById(postID).select('-_id title body').lean()
You had some bugs that probably would interfere, I did a pull request to fix them: https://github.com/Fadedrifleman/socialMediaAppBackend/pull/1
But the main part would be this:
const getPost = async (req, res) => {
try {
if (req.body.id) {
const user = await User.findById(req.body.id);
await user.populate("post");
res.status(200).json(user.post);
return;
}
const posts = await Post.find({ access: 'public' }).select('-access');
res.status(200).json(posts);
} catch (error) {
res.status(500).json({ message: error.message });
}
};

Api Post 400 Bad Request

I'm making a post API on a dummy node project; it worked fine there, but implemented the same API on the main project I got the 400 Bad request error while running this API on a post.
Route js
router.post("/add",(req, res) => {
const planName = req.body.planName;
const planPrice = req.body.planPrice;
const planMode = req.body.planMode;
const planStatus = req.body.planStatus;
const newAddon = new Addon({
planName,
planPrice,
planMode,
planStatus,
});
console.log("newAddon", newAddon)
newAddon.save()
.then(() => res.json("Addon added"))
.catch(err =>
res.status(400).json("Error in Add Addon route")
);
});
Schema
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const addonsSchema = new Schema(
{
planId: {type: Number,required: true},
planName: {type: String,required: true},
planPrice: {type: Number,required: true},
planMode: {type: String, required:true},
planStatus: {type: String, required:true}, //active or inactive
},
{timestamps: true},
);
const Addon = mongoose.model("Addons", addonsSchema);
module.exports = Addon
index.js
const addonRouter = require('./routes/addon')
app.use('/addons',addonRouter)
Postman Screenshot
You'll need to provide planId as well in the payload, since you've defined required as true.
You've 2 ways to solve this:
Set the value of planId equal to _id field that mongodb creates automatically before inserting. You can do this with a preSave hook on the model.
addonsSchema.pre("save", (next) => {
// only triggered when creating new records
if (this.isNew) {
this.planId = this._id;
}
next();
});
And your type for planId should be ObjectId.
planId: {type: ObjectId,required: true},
Won't recommend but you can remove required attribute from planId.

Mongoose keep duplicate elements

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.

find in mongoose returns nothing when there is a non existing field in the schema

I have a mongoose Schema like this:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const CitizenSchema = new Schema({
SSN: {
type: Number,
required: true,
unique: true,
},
firstName: {
type: String,
required: true,
},
lastName: {
type: String,
required: true,
}
});
const Citizen = mongoose.model('Citizen', CitizenSchema);
module.exports = Citizen;
and I have a route in my express app that is like this:
router.get('/', (req, res) => {
if (Object.keys(req.query).length === 0) {
// Get all the citizens if there is no query
Citizen.find({})
.select('-SSN')
.then((citizens) => res.send(citizens));
} else {
const query = req.query;
// Add case insensitive to all queries
for (const q in query) {
query[q] = {
$regex: new RegExp(query[q], 'i')
};
}
Citizen.find(query)
.select('-SSN')
.then((citizens) => res.send(citizens))
.catch((err) => res.status(400).send({ msg: 'Bad query request' }));
}
});
So what I do is that if there is not a query, I return all the citizens and if there is a query, I return the query result.
For example if I send a http request to my route with a GET request like http://localhost:5000/api/citizens/, I get all the citizens. And if I send it with a query like http://localhost:5000/api/citizens/?lastName=Doe&firstName=john, I only get the citizens with the first name as John and last name as Doe.
So my problem is that if I try and do a request like http://localhost:5000/api/citizens/?lastName=Doe&q=test, I get an empty array and not the citizens that have Doe as their last name. The query q makes it so that the Citizen.find() does not work properly and does not return the result that I am waiting for.
I will be appreciate it if someone could help me fix this.
You can try using $or in your queries: https://kb.objectrocket.com/mongo-db/or-in-mongoose-1018

How to remove an array element from Mongodb

I'm new to MEAN stack. I'm trying to implement this and this. I'm using $pull. But they ain't working maybe because my structure in mongodb is different from theirs. So let me first show you that:
downvoters is an string array that contains userids who downvoted that particular article. Lets say the person on downvoters[2] i.e 53et853rf later upvoted this article.Then his userid should be removed from downvoters list. Here is my code:
api.js
router.put('/update-upvotes', (req, res) => {
let articleData = req.body;
...
Article.update(
{articleid: '5p4aqbryi'},
{ $pull: { downvoters: '53et853rf' } }
);
Article.findOneAndUpdate(
{articleid: '5p4aqbryi'},
{upvotes: articleData.upvotes, upvoters: articleData.upvoters}, useFindAndModify=false,
(error, user) => {
if(error) {
...
}
else {
...
}
})
})
But that id is not deleted. There's no error or warning on console. Please correct me.
And here is the schema
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const articleSchema = new Schema({
articleid: String,
title: String,
content: String,
date: String,
contributor: String,
upvotes: Number,
upvoters: [],
downvotes: Number,
downvoters: []
})
module.exports = mongoose.model('article', articleSchema, 'articles');
PS: Let articleId and downvoter id be hardcoded now. I'll make them dynamic later.
Both upvoters and downvoters are String arrays so your Mongoose schema should look like below:
const articleSchema = new Schema({
articleid: String,
title: String,
content: String,
date: String,
contributor: String,
upvotes: Number,
upvoters: [String],
downvotes: Number,
downvoters: [String]
});
You should also keep in mind that update() is an asynchronous operation which needs to be awaited or handled as Promise so:
let opResult = await Article.update(
{articleid: '5p4aqbryi'},
{ $pull: { downvoters: '53et853rf' } }
);
or
Article.update(
{ articleid: '5p4aqbryi' },
{ $pull: { downvoters: '53et853rf' } }
).then(opResult => console.log(opResult));

Categories