Mongodb: Cannot see data of the Embedded Document via command - node.js

For mongodb's embedded document, I don't know why the data is not saved in the database or something else might be wrong? I tried to print out everything to make sure it works till the last step. But still got nothing when querying the embedded document, as you can see from below.
My schema:
// create competitorAnalysisSchema
var CompetitorAnalysis = new Schema({
firstObservation: { type: String },
secondObservation: { type: String },
thirdObservation: { type: String },
brandName: { type: String },
productCategory: { type: String },
photo1: { data: Buffer, contentType: String },
photo2: { data: Buffer, contentType: String },
photo3: { data: Buffer, contentType: String },
photo4: { data: Buffer, contentType: String }
});
// create UserSchema
var UserSchema = new Schema({
userName: { type: String, required: true, unique: true },
email: { type: String, required: true, unique: true },
password: { type: String, required: true },
currentDemo: { type: String },
nextDemo: { type: String },
startTime: { type: String },
startLocation: { type: String },
arriveTime: { type: String },
arriveLocation: { type: String },
leaveTime: { type: String },
leaveLocation: { type: String },
competitorAnalysis: [CompetitorAnalysis],
created_at: Date,
updated_at: Date
});
var User = mongoose.model('User', UserSchema);
module.exports = User;
In my index.js, all debug messages can be successfully printed out.:
// on routes that end in /users/competitorAnalysisTextData
// ----------------------------------------------------
router.route('/users/competitorAnalysisTextData/:userName')
// update the user info (accessed at PUT http://localhost:8080/api/users/competitorAnalysisTextData)
.put(function(req, res) {
// use our user model to find the user we want
User.findOne({ userName: req.params.userName}, function(err, user) {
if (err)
res.send(err);
console.log('Got the user!');
// update the text data
user.competitorAnalysis.firstObservation = req.body.firstObservation;
user.competitorAnalysis.secondObservation = req.body.secondObservation;
user.competitorAnalysis.thirdObservation = req.body.thirdObservation;
user.competitorAnalysis.brandName = req.body.brandName;
user.competitorAnalysis.productCategory = req.body.productCategory;
console.log('req.body.firstObservation: %s', req.body.firstObservation);
console.log('user.competitorAnalysis.firstObservation: %s', user.competitorAnalysis.firstObservation);
console.log('Save the text data for competitorAnalysisTextData!');
// save the user
user.save(function(err) {
if (err)
res.send(err);
res.json({ message: 'User updated!' });
console.log('user.competitorAnalysis.firstObservation: %s', user.competitorAnalysis.firstObservation);
console.log('Finally save the User!');
});
});
})
As in console:
Got the user in "Put"!
req.body.firstObservation: 3
user.competitorAnalysis.firstObservation: 3
Save the text data for competitorAnalysisTextData!
user.competitorAnalysis.firstObservation: 3
Finally save the User!
Problem
However, when I search in my mongodb database, there is no data saved for the embedded document:
...
"leaveTime" : "Your Current Time:\n 2016-08-23 10:27:45 AM",
"leaveLocation" : "Your Current Address:\n 1\nInfinite Loop\nCupertino\n95014",
"competitorAnalysis" : [ ]
}
> db.users.find({"competitorAnalysis.firstObservation" : "3"}).pretty()
>
Empty here!
I'm new to mongodb. It'll be great if I can get some hints on where else I can check or what the problem might be.
Update
Output of collection:
> db.users.find().pretty()
{
"_id" : ObjectId("57ba5f41ad8858305a5d3e58"),
"created_at" : ISODate("2016-08-22T02:11:13.968Z"),
"updated_at" : ISODate("2016-08-24T19:42:56.311Z"),
"nextDemo" : "12:00pm - 3:00pm, Whole Foods Market, 5880 Centre Ave, Pittsburgh PA 15206",
"currentDemo" : "9:00am - 1:00pm, Whole Foods Market, 5880 Centre Ave, Pittsburgh PA 15206",
"password" : "<3da4dafc c96e05cd 855da8b3 ff0bf074 8156ec4b b9f1a002 ba907bcc d5e4aa5b fcd2fef9 dec240cd 86489978 7d85cec8 f11eae1c 7b60b2cc 6693da1a 4eae3a73>",
"email" : "chenya#gmail.com",
"userName" : "Chenya",
"__v" : 1,
"startLocation" : "Your Current Address:\n 10141\nBilich Pl\nCupertino\n95014",
"startTime" : "Your Current Time:\n 2016-08-24 03:42:42 PM",
"arriveTime" : "Your Arriving Time:\n 2016-08-24 03:42:44 PM",
"arriveLocation" : "Your Arriving Address:\n 10131\nBilich Pl\nCupertino\n95014",
"leaveTime" : "Your Current Time:\n 2016-08-23 10:27:45 AM",
"leaveLocation" : "Your Current Address:\n 1\nInfinite Loop\nCupertino\n95014",
"competitorAnalysis" : [ ]
}
>

These statements are the problem:
user.competitorAnalysis.firstObservation = req.body.firstObservation;
user.competitorAnalysis.secondObservation = req.body.secondObservation;
user.competitorAnalysis.thirdObservation = req.body.thirdObservation;
user.competitorAnalysis.brandName = req.body.brandName;
user.competitorAnalysis.productCategory = req.body.productCategory;
You're treating your competitorAnalysis array as if it were an object.
I don't work with Mongoose, so don't know the syntax, but you want to do something like this instead:
user.competitorAnalysis.push({
firstObservation: req.body.firstObservation,
secondObservation: req.body.secondObservation,
thirdObservation: req.body.thirdObservation,
brandName: req.body.brandName
productCategory: req.body.productCategory
});

Related

Node: all data is saved except the array field

I have a problem saving this object that has an array as a property, everything is being saved except the array.I don't know what point I'm missing, if the problem was the approach to solving the problem if there is a better way to solve it
json sent
data:'2020-08-14'
hora:'21:04'
identificador:'MSG 001'
mensagem:'TEST 001'
periocidade:(7) ['Segunda-Feira', 'Terça-Feira', 'Quarta-Feira', 'Quinta-Feira', 'Sexta-Feira', 'Sabado', 'Domingo']
__proto__:Object```
Model
``new Schema({
identificador: {
type: String
},
hora: {
type: String
},
data: {
type: String
},
mensagem: {
type: String
},
ativo: {
type: Boolean,
default :true
},
periodicidade : [{
type : String
}],
date_time : {
type : Date,
default: Date.now
}``
Action
``routes.route('/add').post(function(req, res) {
let regra = new Mensagem(req.body);
regra.save()
.then(regra => {
res.status(200).json({'msg': 'added successfully'});
})
.catch(err => {
res.status(400).send('adding new failed');
});
});``

Nested MongoDB document issue (Mongoose and Node Js)

I am facing some issues while inserting data into nested documents structure of mongoDb.
Following is the Mongoose Model:
const funnel = new mongoose.Schema({
funnelName:{
type:String,
unique:true
},
group: String,
category: String,
funnelStep: {
stepType: String,
stepName: String,
stepPath: String,
isTracking: Boolean,
viewsStorage: []
} })
Below is the push I am sending to Db:
router.post('/createFunnel',async (req,res)=>{
if(!req.body.funnelName || !req.body.group || !req.body.category)
{return res.status(422).json({error:"Please add all the fields."})}
try{
const funnelSteps = []
funnelSteps.push({
stepType: req.body.stepType,
stepName: req.body.stepName,
stepPath: req.body.stepPath,
isTracking: req.body.isTracking,
viewsStorage: req.body.viewsStorage
})
const funnels = new Funnel({
funnelName : req.body.funnelName,
group : req.body.group,
category : req.body.category,
funnelStep : funnelSteps
})
await funnels.save(function(err){
if(err){
return res.status(422).send({error: err.message})
}
return res.json(funnels)
})
} catch(err){
return res.status(422).send({error: err.message})
} })
Below is the data structure I am sending through postman:
{
"funnelName":"Name-Funnel",
"group":"AVC",
"category":"XYZ",
"funnelStep":[
{
"stepType":"Advert",
"stepName":"Angle",
"stepPath":"google.com",
"isTracking":1,
"viewsStorage":[0,0]
},
{
"stepType":"Optin",
"stepName":"Ver 1",
"stepPath":"fb.com",
"isTracking":1,
"viewsStorage":[1,0]
},
{
"stepType":"Check",
"stepName":"rev-cat",
"stepPath":"google.com",
"isTracking":0,
"viewsStorage":[2,0]
}
] }
Below is the output I am getting in response:
{
"funnelStep": {
"viewsStorage": []
},
"_id": "5ec0ff78a6dfab18f4210e96",
"funnelName": "Testing The Latest Method4",
"group": "AVC",
"category": "XYZ",
"__v": 0
}
How can I fix this issue as my data is not getting inserted properly?
And apart from this, in the viewsStorage array, how to store date and a number which will increment after a certain operations and will get saved in the array according to the dates?
I think there is an issue in the funnelSteps array creation part. You are trying to get data directly from req.body instead of req.body.funnelStep
const funnelSteps = []
req.body.funnelStep.forEach(fs => {
funnelSteps.push({
stepType: fs.stepType,
stepName: fs.stepName,
stepPath: fs.stepPath,
isTracking: fs.isTracking,
viewsStorage: fs.viewsStorage
})
})
Schema
const funnel = new mongoose.Schema({
funnelName:{
type:String,
unique:true
},
group: String,
category: String,
funnelStep: [{
stepType: String,
stepName: String,
stepPath: String,
isTracking: Boolean,
viewsStorage: []
}] })

Mongoose : update a document in a pre save hook

i'm quite new to nodeJS and have some problem i cannot solve...
i would like to update a related document in a pre save hook in mongoose :
No errors, but as a result i always get:
updated:{"n":1,"nModified":0,"ok":1}
so document is never updated.... how can i solve this ? i know i can make all controls before, but pre-hook seems the good place for that.
thanks for your help...
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var suivilotSchema = new Schema({
code_lot: { type: String,Required: 'Code Lot cannot be left blank.' },
site_IMS: { type: String,Required: 'Site IMS cannot be left blank'},
date_plantws: { type: String,Required: 'tws plan prod cannot be left blank'},
nb_server: { type: Number,Required: 'nb Server cannot be left blank.',default: 1},
nb_server_done: { type: Number,Required: 'nb Server done cannot be left blank.',default: 0},
date_created: { type: Date,default: Date.now },
date_updated: { type: Date },
retry: { type: Number },
status: { type: Number}
});
suivilotSchema.pre('save', function (next) {
console.log('***** PRE HOOK suivilot *******');
var self = this;
this.constructor.findOne({'code_lot' : self.code_lot,'date_plantws' : self.date_plantws, 'retry' :
self.retry },function (err,existinglot) {
if (!existinglot){
console.log('SUIVILOTS : pas de resultat');
next();
}
else{
console.log('SUIVILOTS : lot exists: ',existinglot._id);
existinglot.updateOne({ '_id' : existinglot._id }, { $inc:{'nb_server' : 1}
},function(err,updated){
if(err)
console.log("Error during increment server :"+err);
console.log('updated:'+JSON.stringify(updated));
console.log('updated:'+JSON.stringify(existinglot));
});
}
});
});

updating values in nested object arrays Mongoose Schema

I have my schema designed like this
const templateSchema = new Schema({
Main: {
text: String,
textKey: String,
index: String,
part: String,
overallStatus: String,
subjects: [
{
id: String,
text: String,
textKey: String,
index: String,
type: String,
comment: String,
image: String,
answer: String,
}
and I have to update subjects text and subject id and I am doing it like this
router.post("/edit", (req, res, next) => {
Template.findOneAndUpdate({
id: req.body.id,
text: req.body.text
}).then(updatedTemp => {
console.log(updatedTemp);
if (updatedTemp) {
res.status(200).json({
message: "Template updated.."
});
} else {
res.status(404).json({
message: "Checklist not found"
});
}
});
});
it returns template updated and status 200 but it doesn't update the new values. How can i access subject ID and subject text in this schema
so, According to the provided schema,
you should find inside the array, and update there,
you could do something like this:
router.post("/edit", (req, res, next) => {
Template.update(
{
"Main.subjects.id": req.body.oldId,
"Main.subjects.text": req.body.oldText,
//you can pass some more conditions here
},
{
$set: {
"Main.subjects.$.id": req.body.id,
"Main.subjects.$.text": req.body.text
}
}
)
.then(updated => {
if (updated.nModified) {
res.status(200).json({
message: "Template updated.."
});
} else {
//not updated i guess
}
})
.catch(error => {
//on error
});
});
so payload in body you need to pass :
oldId : <which is currently there>,
oldText: <which is currently there>,
id: <by which we will replace the id field>
text:<by which we will replace the txt>
NOTE:
assuming , id or text will be unique among all the docs.
sample data:
{
"_id" : ObjectId("5be1728339b7984c8cd0e511"),
"phases" : [
{
"phase" : "insp-of-install",
"text" : "Inspection of installations",
"textKey" : "",
"index" : "1.0",
"subjects" : [...]
},...]
}
we can update text here like this [in the top most level]:
Template.update({
"_id":"5be1728339b7984c8cd0e511",
"phases.phase":"insp-of-install",
"phases.text":"Inspection of installations"
},{
"$set":{
"phases.$.text":"Some new text you want to set"
}
}).exec(...)
but, incase you want to do deep level nested update,
you can have a look at this answer : here by #nem035

Updating multiple sub-documents with Mongoose and Node

I have a Model wich contains an array of sub-documents. This is a Company:
{
"_id" : ObjectId(":58be7c236dcb5f2feff91ac0"),
"name" : "sky srl",
"contacts" : [
{
"_id" : ObjectId("58be7c236dcb5f2feff91ac2"),
"name": { type: String, required: true },
"company" : ObjectId("58be7c236dcb5f2feff91ac0"),
"email" : "sky#gmail.com",
"chatId" : "",
"phone" : "123456789",
"name" : "John Smith"
},
{
"_id" : ObjectId("58be7f3a6dcb5f2feff91ad3"),
"company" : ObjectId("58be7f3a6dcb5f2feff91ad1"),
"email" : "beta#gmail.com",
"chatId" : "",
"phone" : "987654321",
"name" : "Bill Gaset"
}
],
"__v" : 1
}
I have several companies, and I want to update the field chatId of all the contacts in all the companies, that matches the phone I am searching for.
My Schema definitions (simplified, for focusing on question):
var contactSchema = new Schema({
[...]
phone: { type: String, required: true },
email: { type: String },
chatId: { type: String },
company: Schema.Types.ObjectId,
});
var companySchema = new Schema({
name: { type: String, required: true },
type: { type: String, default: "company" },
contacts: [contactSchema]
});
I tried
var conditions = { "contacts.phone": req.body.phone };
var partialUpdate = req.body; //it contains 'req.body.phone' and 'req.body.chatId' attributes
Company.find(conditions).then(
function (results) {
results.map( function(companyFound) {
companyFound.contacts.forEach(function (contactContainer){
if (contactContainer.phone == partialUpdate.phone) {
contactContainer.chatId = partialUpdate.chatId;
Company.save();
companyFound.save();
contactContainer.save();
results.save();
}
//not sure of what to save, so i save everything
companyFound.save();
contactContainer.save();
results.save();
});
});
});
following this answer; but it doesn't works. It does not save anything, what I'm doing wrong?
I have never done this before, but worth a try.
Maybe you need to use $elemMatch.
// find the companies that have contacts having the phone number
Company.find().where('contacts', { $elemMatch: { phone: req.body.phone }}).exec(function (err, companies) {
if (err) {
console.log(err);
return;
}
// see if you can at least get the query to work
console.log(companies);
async.eachSeries(companies, function updateCompany(company, done) {
// find and update the contacts having the phone number
company.contacts.forEach(function (contact, i, arr) {
if (contact.phone == req.body.phone) {
arr[i].chatId = req.body.chatId;
}
});
company.save(done);
}, function allDone (err) {
console.log(err);
});
});
Note, I am using async.js to do async operations on multiple items.
Honestly, I would have simply made contacts an array of Contact references -- much easier to query and update.
Just for the records: I did this to make it work without async.js:
Company.find().where('contacts', { $elemMatch: { phone: req.body.phone } })
.exec(function (err, companies) {
if (err) {
console.log(err);
return;
}
console.log("companies: " + JSON.stringify(companies, null, 4));
companies.forEach(function (company) {
company.contacts.map(function (contact, i, arr) {
if (contact.phone == req.body.phone) {
arr[i].telegramChatId = req.body.telegramChatId;
}
});
company.save();
},
function allDone(err) {
console.log(err);
});
});`

Resources