Updating an Array of Objects (Mongoose Schema) - Node.js - node.js

This is my Room Schema room.js:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var config = require('../../config.js');
module.exports = mongoose.model(config.DATA_TYPE.ROOM, new Schema({
name: String,
guide: String,
leader: String,
partecipants_counter : { type: Number, default: 0},
event_counter : { type: Number, default: 0},
creation: { type: Date, default: Date.now},
partecipants: [],
events: [{ type: Schema.Types.ObjectId, ref: config.DATA_TYPE.EVENT}]
}));
And this is my Event Schema event.js:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var config = require('../../config.js');
module.exports = mongoose.model(config.DATA_TYPE.EVENT, new Schema({
id: Number,
data: String,
user: String,
post: { type: Date, default: Date.now}
}, { _id: false }));
This 2 schemas are in the /app/models/ folder, while my manager script is in /app/managers/ folder. My manager contains the following code:
...
var Room = require('../models/room.js');
var Event = require('../models/event.js');
...
createRoom: function(name,leader,guide,callback){
new Room({
name: name,
guide: guide,
leader: leader,
partecipants : [guide,leader],
partecipants_counter : 2
}).save(callback);
},
...
pushEvent(roomId,eventData,sign,callback){
this.getRoomById(roomId,function(err,data){
if(sign == data.leader || sign == data.guide ){
var new_event = {
id: data.event_counter,
data: eventData,
user: sign
}
Room.update(
{ "_id" : roomId},
{ $inc : { event_counter : +1 },
$push : { events:
{ id : new_event.id,
data : new_event.data,
user : new_event.user
}
}
},function(err,data){
callback(err,new_event);
});
}else{
err = 1;
callback(err);
}
});
},
...
The new_event is correctly created but my update-query doesn't work, everything behave as expected but my database doesn't receive any update: I can't create any event.

Related

express.js mongoose populate 2 model

I'm want to join collection mongoDB but I've 2 model in project.
ADMINDETAIL and ADMINDETAIL get UID from member.model.js .
How I populate that.
queue.model.js
var mongoose = require("mongoose");
var Schema = mongoose.Schema;
var queueSchema = Schema(
{
QUEUE: String,
UID: String,
DATETIME: String,
ADMIN_ID: String,
USERDETAIL:{
type: Schema.Types.String,
ref:"MEMBER"
},
ADMINDETAIL:{
type: Schema.Types.String,
ref:"MEMBER"
},
},
{
collection: "QUEUE"
}
);
var QUEUE = mongoose.model("QUEUE", queueSchema);
module.exports = QUEUE;
member.model.js
var mongoose = require("mongoose");
var memberSchema = mongoose.Schema(
{
UID: {type: String},
NAME: {type: String},
SURNAME: {type: String},
IDNUMBER: {type: String},
PHONE: {type: String},
ADDRESS: {type: String},
},
{
collection: "MEMBER"
}
);
var MEMBER = mongoose.model("MEMBER", memberSchema);
module.exports = MEMBER;
queue.router.js
// GET QUEUE BY USER
router.get("/byuid/:UID", (req, res) => {
var {UID} = req.params;
Queue.find({UID})
.populate({Path:"USERDETAIL",model:"MEMBER"})
.populate({Path:"ADMINDETAIL",model:"MEMBER"})
.exec((err, data) => {
if (err) return res.status(400).send(err);
return res.status(200).send(data);
});
});
Error I got.
TypeError: utils.populate: invalid path. Expected string. Got typeof `object`
change the type of filed from String to ObjectId like this:
USERDETAIL:{
type: Schema.Types.ObjectId ,
ref:"MEMBER"
},
ADMINDETAIL:{
type: Schema.Types.ObjectId ,
ref:"MEMBER"
},
},
add your new data after that you can like this for population:
.populate("USERDETAIL ADMINDETAIL")
or
.populate([{
path: 'USERDETAIL ',
model: 'MEMBER'
}, {
path: 'ADMINDETAIL',
model: 'MEMBER'
}])
I think you are missing []

Mongoose populate returning data without population

I know that this question was asked many many times but i still can't find a solution
So this is my db
Product :
Ingredient :
Schemas :
ingredient.js
const mongoose = require("mongoose");
var IngredientSchema = new mongoose.Schema({
quantity: {
value: Number,
unit: String
},
comment: String,
product: { type: mongoose.Schema.Types.ObjectId, ref: "Product" }
});
module.exports = mongoose.model("IngredientSchema", IngredientSchema);
product.js
const mongoose = require("mongoose");
var ProductSchema = new mongoose.Schema({
name: {
type: String,
default: "",
trim: true,
required: "Name cannot be blank"
},
category: {
type: String,
default: "",
trim: true
},
convertion: [
{
unit_from: String,
unit_to: String,
value_from: Number,
value_to: Number
}
],
default_unit: String
});
const Product = (module.exports = mongoose.model(
"ProductSchema",
ProductSchema
));
this is the populate function :
ingredientRoutes.route("/:id").get(function(req, res) {
let id = req.params.id;
Ingredient.findById(id)
.populate("produit")
.exec()
.then(function(data) {
console.log(data.product, "***");
})
.catch(function(err) {
console.log(err);
});
});
this is the result that i'm getting :
just the id of the product without making the population
Any idea ?

Promise block my reference on MongoDB/Node.js

I use Mongoose to MongoDb with Node.js/React/GraphQL.
I have a document Article who is related to another document Event who is related to several documents Tags. When I try to save my documents I always have a pending promise to into my tags in the Event document.
Result :
- Article is save related to Event
- Event is saved but not related to Tags
- Tags are saved but not related to Event
Expecting :
- Article is save related to Event
- Event is saved and related to Tags
- Tags are saved and related to Event
Two time, when my server was on the beginning is working without pending and error. So I think my problem is a time problem, but I don't know how to resolve it. I try to put some timeout but without success.
I have the following schema in Mongoose/MongoDb
//mode/event.js
'use strict';
//import dependency
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
//create new instance of the mongoose.schema. the schema takes an object that shows
//the shape of your database entries.
var EventSchema = new Schema({
createdAt: {
type: Date,
default: Date.now
},
name: {
type: String,
required: 'Kindly enter the name of the event'
},
description: String,
site_web: String,
themes: {
type: String,
enum: ['Economics', 'Politics', 'Bitcoins', 'Sports'],
default: 'Economics'
},
picture: String,
event_date_start: Date,
event_date_end: Date,
type_event: {
type: String,
enum: ['Confrontation','Standard'],
default: 'Standard'
},
teams: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'Team'
}],
tags: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'Tag'
}]
});
//export our module to use in server.js
module.exports = mongoose.model('Event', EventSchema);
//model/tag.js
'use strict';
//import dependency
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
//create new instance of the mongoose.schema. the schema takes an object that shows
//the shape of your database entries.
var TagSchema = new Schema({
name: {
type: String,
required: 'Kindly enter the name of the tag'
},
});
//export our module to use in server.js
module.exports = mongoose.model('Tag', TagSchema);
//model/article.js
'use strict';
//import dependency
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
//create new instance of the mongoose.schema. the schema takes an object that shows
//the shape of your database entries.
var ArticleSchema = new Schema({
// _id: String,
createdAt: {
type: Date,
default: Date.now
},
event: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Event',
required: 'Kindly enter the event'
},
body: String,
type: {
type: String,
enum: ['Confrontation','Standard'],
default: 'Standard'
},
url_source: String,
themes: {
type: String,
enum: ['Economics', 'Politics', 'Bitcoins', 'Sports'],
default: 'Economics'
},
type_media: {
type: String,
enum: ['video', 'web', 'podcast'],
default: 'web'
},
article_date: Date,
});
//export our module to use in server.js
module.exports = mongoose.model('Article', ArticleSchema);
In my schema Node.js/GraphQL I have the resolve function
createArticle: {
type: ArticleType,
args: {
event: {type: EventCreateType},
body: {type: GraphQLString},
type: {type: articleType},
url_source: {type: GraphQLString},
themes: {type: themesType},
//type_media: {type: new GraphQLList(mediaType)}
type_media: {type: mediaType},
article_date : {type: GraphQLString}
},
resolve: async (source, params) => {
if (params.event) {
var eventparams = params.event;
var tagparams = params.event.tags;
params.event.tags = null;
params.event = null;
var tagIds = [];
//traitement des tags
var inEvent = await EventsModel.findOne({'name':eventparams.name});
if(!inEvent){
inEvent = new EventsModel(eventparams);
if(tagparams){
if(tagparams.length !=0){
tagIds = await tagparams.map(async function(c) {
var inTag = await TagsModel.findOne(c);
if(!inTag){
inTag = new TagsModel(c);
inTag.save(function(err) {
if (err) {
console.log(err);
}});
}
return inTag;
});
console.log('******************************Le tableau**************************');
console.dir(tagIds);
console.log('********************************************************');
//inEvent.tags = tagIds;
Promise.all(tagIds).then(function(savedObjects) {
console.log('********************************************************');
console.log('Le Inside Tab:',savedObjects);
console.log('********************************************************');
// Do something to celebrate?
inEvent.tags = savedObjects;
}).catch(function(err) {
// one or both errored
console.log(err);
});
}
}
inEvent.save(function(err) {
if (err) {
console.log(err);
}});
}
console.log('*******************propriete inEvent*****************************');
console.dir(inEvent);
console.log('********************************************************');
var articleModel = new ArticlesModel(params);
articleModel.event = inEvent;
console.log('***********************propriete Article before save****************');
console.dir(articleModel);
console.log('********************************************************');
articleModel.save(function(err, article) {
if (err) {
console.log(err);
}
if (article) {
return ArticlesModel.findById(article._id)
.populate('article')
.populate('event')
.exec(function(error, articles) {
console.log('article saved: succes')
articles.article.articles.push(articles);
articles.article.save(function(err, article) {
if (err) {
console.log(err);
}
});
return articles;
})
}
});
return articleModel;
}
else{
console.log('verif 3');
}
console.log('verif 4');
}
},

Auto increment sequence in Mongoose

I am trying to implement Auto increment in uisng mongoose.
But I am stuck.
Counter Schema
counter.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var counterSchema = new Schema({
_id: {type: String, required: true},
sequence_value: {type: Number, default: 1}
});
var Counter = module.exports = mongoose.model('Counter', counterSchema);
Product Schema
products.js
var productsSchema = new Schema({
productId: {type: String, require: false},
merchantId: {type: String, required: false}
)}
I have created counter collection and inserted one record inside it.
{
"_id" : "productId",
"sequence_value" : 1
}
Include method to increment the counter in the counter collection
//COUNTER COLLECTION
function getNextSequenceValue(sequenceName){
var sequenceDocument = Counters.findOneAndUpdate({
query:{_id: sequenceName },
update: {$inc:{sequence_value:1}},
new:true
});
return sequenceDocument.sequence_value;
}
Calling method to increment sequence number:
product.productId = getNextSequenceValue("productid");
But it's not working, nothing is getting saved in the products collection?
the next sequence should be
product.productId = getNextSequenceValue("productId"); // camelCase
in the counter collection you have added document with key productId (camelCase) but trying to get sequence with key productid (all lowercase)
mongo CLI
> function getNextSequenceValue(sequenceName){
...
... var sequenceDocument = db.counters.findOneAndUpdate(
... { "_id" : sequenceName },
... { $inc : { sequence_value : 1 } },
... { new : true }
... );
... return sequenceDocument.sequence_value;
... }
>
EDIT-2 with mongoose
var counterSchema = mongoose.Schema(
{
_id: { type: String, required: true },
sequence_value: { type: Number, default: 1 }
}
);
var Counters = mongoose.model('Counters', counterSchema);
var productsSchema = mongoose.Schema({
productId: {type: String, require: true},
merchantId: {type: String, required: false}
});
productsSchema.pre('save', function(next){
var doc = this;
Counters.findOneAndUpdate(
{ _id: 'productId' },
{ $inc : { sequence_value : 1 } },
{ new : true },
function(err, seq){
if(err) return next(err);
doc.productId = seq.sequence_value;
next();
}
);
}
);
var Product = mongoose.model('Product', productsSchema);
var testProduct = new Product({merchantId : 'test'})
testProduct.save(function (err, doc){
console.log('saved ' + doc )
})
output (with generated productId)
saravana#ubuntu:~/node-mongoose$ node app.js
`open()` is deprecated in mongoose >= 4.11.0, use `openUri()` instead, or set the `useMongoClient` option if using `connect()` or `createConnection()`. See http://mongoosejs.com/docs/connections.html#use-mongo-client
Mongoose: counters.findAndModify({ _id: 'productId' }, [], { '$inc': { sequence_value: 1 } }, { new: true, upsert: false, remove: false, fields: {} })
Mongoose: products.insert({ productId: '36', merchantId: 'test', _id: ObjectId("5a5b27b860716d24007df611"), __v: 0 })
saved { __v: 0,
productId: '36',
merchantId: 'test',
_id: 5a5b27b860716d24007df611 }
^C
saravana#ubuntu:~/node-mongoose$

MongoDB Schema - error calling createIndex() for setting expireAt

I wrote my Schema but when I run my Node.js server the following error is showing:
MySchema.createIndex is not a function
I'm using it for setting the expireAt of the record. This is my code:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var config = require('../../config.js');
var tc = new Date();
var te = tc.setSeconds(tc.getSeconds + config.EXPIRE_TOKEN_TIME.ROOM_TOKEN);
var MySchema = new Schema({
name: String,
guide: String,
leader: String,
partecipants_counter : { type: Number, default: 0},
event_counter : { type: Number, default: 0},
createAt: { type: Date, default: tc},
expireAt: { type: Date, default: te},
partecipants: [],
events : [ {
id : Number,
data: String,
user: String
} ]
});
MySchema.createIndex( { "expireAt": 1 }, { expireAfterSeconds: 180 } );
module.exports = mongoose.model(config.DATA_TYPE.ROOM, MySchema);
The syntax should be
MySchema.index( { "expireAt": 1 }, { expireAfterSeconds: 180 } );
More generic example:-
var animalSchema = new Schema({
name: String,
type: String,
tags: { type: [String], index: true } // field level
});
animalSchema.index({ name: 1, type: -1 }); // schema level

Resources