Save JSON object to MongoDB inside String field - javascript

I'm working with Mongodb(mongoose) and node.js (express.js).
The model of DB is:
var messageSchema = new Schema({
_channel: { type: Schema.ObjectId, ref: 'Channel', required: true },
_user : { type: Schema.ObjectId, ref: 'User', required: true },
datetime: { type: Date, required: true },
messageType: { type: String, required: true },
publish: { type: Boolean, default: false },
content: {
title: String,
text: String,
}
});
I want save JSON object inside text field (string).
The JSON object is this:
{ event: 'push',
repository: { id: 53012902, name: 'RestAPI' },
ref: 'refs/heads/master',
commits:
[ { id: 'a10202e5b5157ae5ccd2d77d7d578046693ae404',
url: 'https://github.com/1izpena/RestAPI/commit/a10202e5b5157ae5ccd2d77d7d578046693ae404',
author: '1izpena' } ],
sender: { login: '1izpena', html_url: 'https://github.com/1izpena' } }
I convert this in String, but the result is:
{"event":"push","repository":{"id":53012902,"name":"RestAPI"},"ref":"refs/heads/master","commits":[{"id":"a10202e5b5157ae5ccd2d77d7d578046693ae404","url":"https://github.com/1izpena/RestAPI/commit/a10202e5b5157ae5ccd2d77d7d578046693ae404","author":"1izpena"}],"sender":{"login":"1izpena","html_url":"https://github.com/1izpena"}}
And this result is not a String, I need to keep the same format to parse it later as json object.
Any idea?
Many thanks

Related

MongoDB (mongoose) filter with value in array with reference

I am trying to filter an array in a document in mongoose.
The problem i am having is trying to filter with a value in the array that is in the reference.
To clarify, i have a document containg all the information about a course. In that course i have a array of objects that contains information about students. An object containts a status and also a refrence to the actual user object. I would like filter the students array with a value found in the refrence.
The way i have tested this is as following:
courseModel.findOne({ _id: courseId, 'students.user.startDate': { $lte: startDate } });
My models look like this:
CourseModel:
{
name: {
type: String,
required: true,
maxlength: 50,
minlength: 2,
trim: true
},
description: {
type: String,
required: false,
maxlength: 500,
trim: true
},
type: {
type: String,
required: true,
enum: ['physical', 'online', 'quiz']
},
color: {
type: String,
required: true,
match: /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/
},
events: [
{
type: Schema.Types.ObjectId,
ref: 'event'
}
],
questions: [
{
type: Schema.Types.ObjectId,
ref: 'question'
}
],
educators: [
{
type: Schema.Types.ObjectId,
ref: 'user'
}
],
students: [
{
user: {
type: Schema.Types.ObjectId,
ref: 'user'
},
status: {
type: String,
enum: ['notBooked', 'booked', 'attended', 'completed']
},
lastSlackMessage: {
ts: {
type: String
},
channel: {
type: String
}
},
events: [
{
type: Schema.Types.ObjectId,
ref: 'event'
}
]
}
],
teams: [
{
type: Schema.Types.ObjectId,
ref: 'team'
}
],
createdBy: {
type: Schema.Types.ObjectId,
ref: 'user'
},
updatedBy: {
type: Schema.Types.ObjectId,
ref: 'user'
}
}
UserModel:
{
name: {
type: String,
required: true,
maxlength: 100,
trim: true
},
email: {
type: String,
required: true,
minlength: 5,
match: /^(([^<>()[\]\\.,;:\s#"]+(\.[^<>()[\]\\.,;:\s#"]+)*)|(".+"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
},
employeeId: {
type: String,
required: true
},
slackId: {
type: String,
default: ''
},
teams: [
{
type: Schema.Types.ObjectId,
ref: 'team'
}
],
questions: [
{
question: {
type: Schema.Types.ObjectId,
ref: 'question'
},
status: {
type: String,
enum: ['answered', 'pending', 'notSent']
},
tries: {
type: Number,
default: 0
}
}
],
startDate: {
type: Date,
required: true
}
}
I appreciate any help i can get, thank you!

How to using "find()" with populate field in mongoose?

I have 2 collection in same db. I need to using find() to select only "Events" that have "team" equal "team1"
Thank you very much.
I have try to find by population field but it doesn't work.
This is my Event schema
const Event = mongoose.model('Event', new mongoose.Schema({
title: {
type: String,
required: true,
min: 3
},
eventType: {
type: String,
lowercase: true
},
date: {
type: Date,
default: Date.now()
},
venue: String,
country: String,
callLog: {
type: String,
max: 1000
},
eventImgUrl: [String],
editedBy : {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
},
timestamp: {
type: String,
default: Date.now()
}
}));
This is my User schema
const User = mongoose.model('User', new mongoose.Schema({
username: {
type: String,
required: true,
min: 3,
lowercase: true
},
name: String,
email: String,
team: String,
role: {
type: String,
enum: ['admin', 'creator', 'viewer']
}
}));
This is my Controller
const events = await Event.find()
.populate({ path: 'editedBy', select: ['name', 'team']});
res.send(events);
To find all Events that have a team of "team1":
const team1Events = await Event.find({ team: "team1" });
select just specifies the fields returned. You need to use populate match:
await Event.find()
.populate({ path: 'editedBy', match: { yourField: 'yourmatch' }});

ExpressJS - duplicate key error collection

I have problem with this error when I am creating a new event with category which exists in my database, for example I created an event with category "javascript" and save it to db, and then i tried to create a new event with categories "javascript, html, css" and then i got this error duplicate key error collection
So my schema for event is this:
const EventSchema = new Schema({
title: {
type: String,
required: true,
min: 3,
max: 100
},
featuredImage: {
type: Object,
},
from: {
type: Date,
required: true
},
to: {
type: Date,
required: true
},
location: {
name: {
type: String
},
address: {
type: Object
}
},
description: {
type: String
},
categories: {
type: Array,
trim: true
},
featured: {
type: Boolean
},
created_by: {
type: Schema.Types.ObjectId,
ref: 'User'
},
slug: {
type: String,
default: null
},
registration: {
type: Boolean
},
tickets: [],
allday: {
type: Boolean
},
speakers: [{
type: Schema.Types.ObjectId,
ref: 'User'
}],
attendees: [{
type: Schema.Types.ObjectId,
ref: 'User'
}],
comments: [CommentSchema]
}, {
timestamps: true,
usePushEach: true
});
So basically sending array of strings and i got this error.
You probably have some index defined on categories with the unique flag.
You can list the existing indexes with db.events.getIndexes().
You could drop and recreate the culprit (be careful):
> db.events.dropIndex({categories:1})
> db.events.ensureIndex({categories:1},{sparse:true})

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.

Mongoose not saving all fields

I am trying to save an new document record and some of the fields are being omitted and I have not been able to figure out why.
Here I am setting my order object
var obj = new Order(orderObj);
console.log('orderObj', orderObj);
console.log('obj', obj);
output from console.log:
orderObj { customerId: '5806e2a1759fd9ad7a1f60eb',
products:
[ { productId: '5806e7e3d0073cb4d2946aad',
customerPrice: 100,
notes: 'test',
originalPrice: 99.95,
priceOverride: true } ],
notes: 'some optional order notes',
createdBy: 'test',
total: 99.95 }
obj { customerId: 5806e2a1759fd9ad7a1f60eb,
notes: 'some optional order notes',
createdBy: 'test',
_id: 5808171e802121505e33b252,
shipped: false,
shippedDate: 2016-10-20T01:00:14.019Z,
status: 'Created, Not Shipped',
products:
[ { productId: 5806e7e3d0073cb4d2946aad,
_id: 5808171e802121505e33b253,
quantity: 1 } ] }
Here is my schema:
var orderSchema = new mongoose.Schema({
customerId: { type: mongoose.Schema.Types.ObjectId, ref: 'Customer'},
products: [{
productId: { type: mongoose.Schema.Types.ObjectId, ref: 'Product'},
quantity: { type: Number, default: 1 },
originalPrice: { Type: Number },
customerPrice: { Type: Number },
priceOverride: { Type: Boolean, default: false },
notes: { Type: String }
}],
notes: String,
status: { type: String, default: "Created, Not Shipped" },
orderDate: { type: Date },
shippedDate: { type: Date, default: Date.now },
shipped: { type: Boolean, default: false },
total: {Type: Number, default: 0.00 },
createdBy: { type: String }
}, schemaOptions);
I cannot figure out why total and product fields (originalPrice, priceOverride) are being dropped from the mongoose Schema instance object.
Of course I figured it out right after I posted this question. The type in the Schema was listed as Type instead of type.
[this answer is for the record]
I had same kind of problem and in a schema where maxconnections and roomNo were not being saved,
I had schema
maxconnections: {type: Number | String },
roomNo: {type: Number | String },
changed it to
maxconnections: {type: Number },
roomNo: {type: String},
and now it works fine (!._.)
Also, when sending a request using postman, use content-type as JSON
Otherwise, data in fields will not get stored

Categories