MongoDB Schema - error calling createIndex() for setting expireAt - node.js

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

Related

Product reference is undefiend

I have a model named order. The order model is having a field name product which is a reference to the product model.
My Order model is like
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
const { ObjectId } = mongoose.Schema;
const ProductCartSchema = new Schema({
product: {
type: ObjectId,
ref: Product,
},
name: String,
count: Number,
price: Number,
});
const orderSchema = new Schema(
{
products: [ProductCartSchema],
transaction_id: {},
amount: { type: Number },
address: { type: String },
updated: Date,
user: {
type: ObjectId,
ref: User,
},
},
{ timestamps: true }
);
var Order = mongoose.model('Order', orderSchema);
var ProductCart = mongoose.model('ProductCart', ProductCartSchema);
module.exports = { Order, ProductCart };
And my product model schema is like
var mongoose = require(mongoose);
var Schema = mongoose.Schema;
const { ObjectId } = mongoose.Schema;
const productSchema = new Schema(
{
name: {
type: String,
required: true,
maxlength: 32,
trim: true,
},
description: {
type: String,
required: true,
maxlength: 2000,
trim: true,
},
price: {
type: Number,
required: true,
maxlength: 32,
trim: true,
},
category: {
type: ObjectId,
ref: 'Category',
required: true,
},
stock: {
type: Number,
},
sold: {
type: Number,
default: 0,
},
photo: {
type: Buffer,
contentType: String,
},
},
{ timestamps: true }
);
module.exports = mongoose.model('Product', productSchema);
It's giving me error
Product is not defined on order.js line no 7
Am I need to import product model in this if yes then how I can do that and if not then where is the error
In order to use Product reference in your Order.js Schema, you need to import it.
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
const { ObjectId } = mongoose.Schema;
var Product = require('Product'); <----------------------------------- Import this
const ProductCartSchema = new Schema({
product: {
type: ObjectId,
ref: Product,
},
name: String,
count: Number,
price: Number,
});
const orderSchema = new Schema(
{
products: [ProductCartSchema],
transaction_id: {},
amount: { type: Number },
address: { type: String },
updated: Date,
user: {
type: ObjectId,
ref: User,
},
},
{ timestamps: true }
);
var Order = mongoose.model('Order', orderSchema);
var ProductCart = mongoose.model('ProductCart', ProductCartSchema);
module.exports = { Order, ProductCart };

2dsphere is not a valid type at path `index`

I have 2 schema in mongoose as follows:
PointSchema.js
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const PointSchema = new mongoose.Schema({
type: {
type: String,
enum: ['Point']
},
coordinates: {
type: [Number]
},
index: {
type: '2dsphere',
sparse: true
}
});
module.exports = {
PointSchema
};
DeviceSchema.js
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const PointSchema = require('./PointSchema').PointSchema;
const DeviceSchema = mongoose.Schema({
name: String,
location: {
type: PointSchema,
default: null
}
}, {
collection: 'devices',
timestamps: {
createdAt: 'created_at',
updatedAt: 'updated_at'
}
});
module.exports = mongoose.model('Device', DeviceSchema);
Is there some problem in PointSchema.js as it is giving following error:
TypeError: Invalid schema configuration: 2dsphere is not a valid
type at path index.
Followed this documentation to create PointSchema.js: https://mongoosejs.com/docs/geojson.html
I solved my problem with the next configuration in the model!
module.exports = (mongoose) => {
const DomainSchema = new mongoose.Schema({
domain_id: { type: Number },
name: String,
domain_data: {
type: { type: String },
coordinates: { type: Array },
},
});
DomainSchema.index({ domain_data: '2dsphere' });
return mongoose.model('Domain', DomainSchema);
};

How do I index a field on a mongoose Schema that uses a discriminator?

The error started after I started using the discriminator.
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const Base = require("../config/Base");
const Refill = Base.discriminator(
"Refill",
new Schema({
cylinderSize: { type: Number, required: true },
cylinderSwap: { type: Boolean, required: true },
quantity: { type: Number, required: true },
location: {
type: { type: String },
coordinates: [Number]
}
})
);
Refill.index({ location: "2dsphere" });
module.exports = mongoose.model("Refill");
This returns the error Refill.index is not a function
In Mongoose, indexes must be created on schemas, not models. In your case, the Refill object is a model. One approach is to implement this in three steps:
Create the schema
Add the index to the schema
Create the model
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const Base = require("../config/Base");
const refillSchema =
new Schema({
cylinderSize: { type: Number, required: true },
cylinderSwap: { type: Boolean, required: true },
quantity: { type: Number, required: true },
location: {
type: { type: String },
coordinates: [Number]
}
});
refillSchema.index({ location: "2dsphere" });
const Refill = Base.discriminator("Refill", refillSchema);
module.exports = mongoose.model("Refill");
I just took out the Refill.index({ location: "2dsphere" }); and the rest of my code is working fine apparently indexing that field wasn't necessary.

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$

Updating an Array of Objects (Mongoose Schema) - 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.

Resources