Saving an array to MongoDB database - node.js

Let's say I have a schema for my MongoDb collection.
module.exports = (mongoose, Schema) => {
let eventSchema = new Schema({
name: String
values: ???
});
return mongoose.model('Event', eventSchema);
};
I receive a json like this one:
{"1965": 10000000, "1966": 20000000, "1967": 300000}
I want this array to be in the "values" field of the eventSchema. How do I save it to my db?
Years vary, and the number of objects in array is always different.

Try something like this:
const payload = { name : "test" , values : {"1965": 10000000, "1966": 20000000, "1967": 300000}
}
const event = new Event(payload)
event.save(function (err) {
if (err) return console.log(err);
// saved!
});
and make sure your schema is :
let eventSchema = new Schema({
name: String
values: Object
});

Related

Get the _id of the sub-document from mongoose findOne query

The schema of my Sample model is:-
var nameSchema = new mongoose.Schema({
firstname:String,
lastname:String
})
var sampleSchema= new mongoose.Schema({
number: {
type: String
},
name :{
type : [nameSchema]
}
});
I am trying to update the first and last name by searching them by their number property by making use of Sample.findOne({number:number}). And i am performing the update operation in the following manner:-
module.exports.updateNumber = function(req, res){
var number= req.body.number;
var lname= req.body.lname;
var fname= req.body.fname;
Sample
.findOne({number:number})
.select('name')
.exec(function(err, doc){
console.log(doc)
var this_id;
var thisService = doc.name.id('this_id');
thisService.firstname=fname;
thisService.lastname=lname;
doc.save(function(err, update) {
if (err) {
res
.status(500)
.json(err);
} else {
res
res.render('done')
}
});
})
}
If i console log the output i got is:
{ _id: 5bc5d71f47ff14361c0639d1,
name:
[ { _id: 5bc5d71f47ff14361c0639d2,
firstname: 'firstname',
lastname: 'lastname' } ] }
Is there any way, i could store _id: 5bc5d71f47ff14361c0639d2 in 'this_id' variable, so that this updation would be possible
name is an array, so if you want the first _id then name[0]._id would suffice, if you want an array of all values for _id in name, then name.map((person) => person._id) would give you an array of _id
However, more details about the context of this object would help give a better answer.

insert and insertOne not a function and update not creating mongo ID

I thought I could read my way to this solution, but I cant see what im doing wrong.
Here is my model:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var inspectSchema = new Schema({
_id: Object, // Mongo ID
property: String, // Property ID
room: String, // The room Name
item: Array // The Items text
});
module.exports = mongoose.model('inspectModel', inspectSchema, 'inspect');
And here is where I try to insert or insertOne
var inspectModel = require('../../models/inspectModel');
var inspectTable = mongoose.model('inspectModel');
inspectTable.insert(
{
"property" : inspectRecord.property,
"room" : inspectRecord.room,
"item" : inspectRecord.item
},
function (err, res) {
if (err) { return reject({err:true, err:"addInspect ERROR" + err}) }
else {
show("=====RESOLVE addInspect=====")
return resolve();
}
})
I tried
inspectTable.insert
inspectModel.insert
inspectTable.insertOne
inspectModel.insertOne
No matter what I always get
TypeError: inspectTable.insert is not a function
I also tried just update with { upsert: true } but then the mongo ID becomes null.
Any ideas?
The method you're looking for is create:
inspectTable.create(
{
"property" : inspectRecord.property,
"room" : inspectRecord.room,
"item" : inspectRecord.item
}, ...
However, your schema definition of _id: Object is likely wrong. Just leave any definition of _id out of your schema and it will use the default ObjectId, which is likely what you want.
You can try this
var insert_table = new inspectTable(
{
"property" : inspectRecord.property,
"room" : inspectRecord.room,
"item" : inspectRecord.item
});
insert_table.save(function (err, res) {
if (err) { return reject({err:true, err:"addInspect ERROR" + err}) }
else {
show("=====RESOLVE addInspect=====")
return resolve();
}
});

MongoDB and mongoose: how to add an object if it doesn't already exist

I am having some trouble with mongoDB/mongoose and node.js. I am used to SQL, and mongoDB is...hard! Here is my schema:
var mongoose = require('mongoose');
mongoose.Promise = global.Promise;
var itemSchema= mongoose.Schema({
item_info : {
user_id : Number,
location : String,
item_id : Number,
title : String
},
item_hist : {
user_id : Number,
location : String,
item_id : Number,
founddate : String
}
});
module.exports = mongoose.model('item', itemSchema);
And I can add a new item by doing this:
var item= require('./app/models/item');
var item= new item();
item.item_info.user_id = 12345;
item.item_info.location = 'This address';
item.item_info.item_id = 4444;
item.item_info.title = 'New item';
item.save(function(err)
{
if (err) throw err;
});
What I want to be able to do is say: "look for an item with item_info.item_id 5555. if it exists, do nothing. if it doesn't exist, then add it to the database." I've read through so much mongodb and mongoose documentation, but between using dot notation and accessing through nodejs instead of command line mongodb, I still can't figure out how to do this. SQL seemed so much easier!
Just use this -
var query = { user_id: 12345, location: "This address", item_id: 4444, title: "New item" },
options = { upsert: true };
Model.findOneAndUpdate(query.item_id, query, options, function(error, result) {
if (error) return;
// do something with the document
});

Mongoose: $inc not working

I am not sure what the problem is, as I've read numerous examples.
Taken from what I was advised here in this StackOverFlow(Mongoose - Increment a value inside an array of objects), I changed the format of poll at ease to accommodate what was recommended.
So I was able to create a document format as so:
{
"_id": "584c4160b3b22e1bdad59bce",
"title": "Food",
"description": "test",
"labelOptions": {
"burger": 29,
"coffee": 44,
"pizza": 23
},
"date": "Dec 10, 2016",
"__v": 0
}
Here's what I have so far:
Poll Model
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const pollData = new Schema({
title: String,
description: String,
labelOptions: {},
date: String
})
module.exports = mongoose.model('PollData', pollData)
Using express and mongoose, here's what I have:
app.put('/polls/:id', function(req, res){
let id = req.params.id;
let labelOption = req.query.labelOption;
let query = `labelOptions.${labelOption}`
Poll.findByIdAndUpdate(
id,
{$inc: { query: 1 } },
function(err, document){
console.log(err)
console.log(document)
}
)
})
In my terminal, I see that console.log(document it receives the document I was looking for but it does not update the value at all.
Am I setting up the Model correctly? Or does Mongoose does not support template strings?
***update
This is snippet of how I am creating documents
let labelOptions = {}; <=== creating object literal to hold as placeholder
const title = req.body.title;
const description = req.body.description;
req.body.labelOptions.split(/,\s*/).map( prop =>{
labelOptions[prop] = 0 // set counter to default 0
})
const poll = new Poll({
title: title,
description: description,
labelOptions: labelOptions,
date: moment().format('MMM D, YYYY')
});
poll.save(function(err) {
if (err) { return next(err); }
res.json({ message : 'Poll added!'})
});
After doing some research across the internet, I found the reason why it wasnt working: You can't initialize objects with 'dynamic' keys.
Source: Mongoose update on a string variable not working?
By knowing that, it was just a simple solution to initialize an literal object as so:
let id = req.params.id;
let labelOption = req.query.labelOption;
let query = "labelOptions." + labelOption
let obj = {
[query] : 1
}
Poll.findByIdAndUpdate(
id,
{$inc: obj },
function(err, document){
console.log(err)
console.log(document)
}
)

Mongoose sub Docs CastError

I am new to MongoDB and MongooseJS. I'm also new to nodeJs.
I have an Angularjs project using Typescript. This project work with a "container" json, which itself contains some properties and a testList, which is a json object containing some properties and a fileList, containing an itemList.
So it's like this :
export class Container{
data:string="";
testList:Test[];
}
export class Test {
moredata:string="";
fileList:File[];
}
export class File {...}
etc.
I send this JSON to my nodejs server. I'm using bodyparser to get the json from the req.body object.
Server side, my mongoose Schema are exactly like my angularjs classes, so they look like this :
/*************** mongoose schemas **************/
// item.js
var mongoose = require('mongoose');
module.exports = mongoose.model('Item', {
Content : {type : Object, default: ''}
});
// file.js
var mongoose = require('mongoose');
var Item = require('./item');
var schema = new mongoose.Schema({
Data : {type : String, default: ''},
ItemList: {type: [Item], default:[]}
});
// test.js
var mongoose = require('mongoose');
var File = require('./file');
var schema = new mongoose.Schema({
Data: {type:String},
FileList: {type:[File], default:[]}
});
// container.js
var mongoose = require('mongoose');
var Test = require('./test');
var schema = new mongoose.Schema({
Name : {type : String, default: '', index:true, unique:true, required: true, dropDups:true},
Test : {type:[Test], default:[]}
});
If I try to create a new Container object (Mongoose object) and assign it the json from req.body, it bugs : CastError.
If I re-create each sub document from JSON and save the main doc, it bugs too : CastError.
I don't know how to achieve this. It worked before but my mongoose schema where using [mongoose.Schema.Types.Mixed] type for sub docs, and not the "real" types. Fact is, with Mixed I had no _id on sub docs, which I want.
Using real sub docs types, I can see in logs that the _id is created, but all the lists are empty.
Here is my nodejs code :
/*************** nodejs **************/
app.post('/api/container', bodyParser.urlencoded({extended:true}), bodyParser({limit:'50mb'}), bodyParser.json(), function(req, res) {
var test = req.body._test;
var testList = [];
var fileList;
var itemList;
var itemObj;
var fileObj;
var testObj;
for(var i in test){
fileList = [];
for(var j in test[i]._fileList){
itemList = [];
for(var k in test[i]._fileList[j]._itemList){
itemObj = new Item({
Content : test[i]._fileList[j]._itemList[k]._content
});
itemList.push(itemObj);
console.log('item pushed : ' + itemObj + ' and length : ' + itemList.length);
// logs gives info OK.
}
fileObj = new File({
Data: locales[i]._fileList[j]._data,
ItemList: itemList
});
fileList.push(fileObj);
console.log('file pushed : ' + fileObj);
// logs gives info NOK. The ItemList is empty : [], instead of a 70+ item list.
}
testObj = new Test({
Data: locales[i]._data,
FileList: fileList
});
testList.push(testObj);
console.log('test pushed : ' + i);
// once again, logs are NOK : the FileList is empty : []
}
// use mongoose to save the project in the database
new Container({
Name : req.body._name.toLowerCase().trim(),
Test: testList
}).save(function(err, container, count){
if(err){
console.log('erreur : ');
console.log(err);
// we enter here as we have this error :
/*
{ [CastError: Cast to undefined failed for value "
{
_id: 5727ebf95a76ff0011374928,
FileList: [],
Data: 'data'
},
{
_id: 5727ebf95a76ff0011374970,
FileList: [],
Data: 'other data'
}" at path "Test"]
message: 'Cast to undefined failed for value "
{ _id: 5727ebf95a76ff0011374928,\n FileList: [],\n Data: \'data\' },
{ _id: 5727ebf95a76ff0011374970,\n FileList: [],\n Data: \'other data\'}"
at path "Test"',
name: 'CastError',
type: undefined,
value: [{"_id":"5727ebf95a76ff0011374928","FileList":[],"Data":"data"},{"_id":"5727ebf95a76ff0
011374970","FileList":[],"Data":"other data"}],
path: 'Test' }
*/
res.status(403).json({error: 'error'});
} else {
console.log('saved ! ');
res.json(container);
}
});
});
I'm not used to post here, I'm more a reader :) Anyway if my post is not appropriated please inform me and I'll move / edit it correctly.
Thanks for your time.
Checked, and working !
So my error was to use the models of my objects in mongoose schema instead of their Schema.
I'm now exporting both models and schema on each object, and using schema for schema definitions, and models for requests. Finally rid of this bug ! :)
/* Mongoose object definitions */
// grab the mongoose module
var mongoose = require('mongoose');
var child = require('./child').schema; // getting the child schema
// define our parent model
var parentSchema = new mongoose.Schema({
Name : {type : String, default: ''},
ChildrenList: {type: [Child], default:[]}
});
var parentModel = mongoose.model('Parent', parentSchema);
// module.exports allows us to pass this to other files when it is called
module.exports = {
model: parentModel, // exporting model for requests
schema: parentSchema // exporting schema for others schema using "Parent"
};
And the code used for requests :
var Child = require('./models/child').model; // here using model
var Parent = require('./models/parent').model; // here using model
new Parent({
Name : req.body._name.toLowerCase().trim(),
ChildrenList : childrenList // variable defined somewhere
}).save(function(err, parent, count){
if(err){
res.status(403).json({error: 'too bad'});
} else {
res.json(parent);
}
});

Resources