Mongoose insertMany ignores unique:true - mongodb

I have the following code
const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/mydb', { useNewUrlParser: true, useUnifiedTopology: true });
mongoose.set('useCreateIndex', true);
mongoose.set('debug', true);
let db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', () => {
console.log('connected');
let DocumentSchema = mongoose.Schema({ name: { type: String, unique: true } });
let Document = mongoose.model('Document', DocumentSchema, 'documents');
const docs = [{ name: 'd1' }, { name: 'd1' }, { name: 'd2' }, { name: 'd3' }];
Document.insertMany(docs, (err, docs) => {
if (err) {
console.log(err);
}
else {
console.log('Documents inserted', docs.length);
}
});
});
InsertMany method will add all the objects duplicating them. I cannot find the problem here. Any help is appreciated.
Thanks

Found the issue. When defining the schema you must specify index:true. The documentation stated that if unique:true index is optional. It seems it is not so.
let DocumentSchema = mongoose.Schema({ name: { type: String, unique: true, index: true } });

Related

data can be seen in console but in db it is not inserting using mean stack

my model(cart.js)
const mongoose = require('mongoose');
const Schema = mongoose.Schema
var cartSchema = new Schema({
prodId: { type: Number },
img: { type: String },
qnt: { type: Number },
amt: { type: Number },
name: { type: String },
address: {type: String}
})
module.exports = mongoose.model('cart', cartSchema,'carts');
=====>
my routes(cart.js):
router.post('/', (req, res) => {
let cartData = req.body
let cart = new Cart(cartData)
console.log(req.body)
cart.save((error, cart) => {
if(error){
console.log("Error: "+ error)
}
else{
res.status(200).send(cart)
}
})
})
there is no error in console .everything is fine but getting only _id,_v in database.
what is wrong ?please help me.
thanks in advance

How to insert auto increment number in mongoose

Tried to insert auto increment number for serial number in mongodb using mongoose and nodejs but not working.Where i want to update my code to find solution.If anyone knows please help to find solution.
subs.model.js:
const mongoose = require('mongoose');
var subscriberSchema = new mongoose.Schema({
_id: {type: String, required: true},
email: {
type: String
}
}, {
versionKey: false,
collection: 'subscribers'
});
module.exports = mongoose.model('Subscribers', subscriberSchema);
data.controller.js:
module.exports.subscribeMail = (req, res, next) => {
var subscribeModel = mongoose.model("Subscribers");
var subscribemailid = req.query.email;
var subscribe = new subscribeModel({
email: subscribemailid
});
var entitySchema = mongoose.Schema({
testvalue: { type: String }
});
subscribe.save(function(error, docs) {
if (error) { console.log(error); } else {
console.log("subscribe mail id inserted");
console.log(docs)
res.json({ data: docs, success: true });
}
});
entitySchema.pre('save', function(next) {
var doc = this;
subscribe.findByIdAndUpdate({ _id: 'entityId' }, { $inc: { seq: 1 } }, function(error, counter) {
if (error)
return next(error);
doc.testvalue = counter.seq;
next();
});
});
};
If i use above code inserting data into mongodb like below:
_id:5f148f9264c33e389827e1fc
email:"test#gmail.com"
_id:6f148f9264c33e389827e1kc
email:"admin#gmail.com"
But i want to insert like this
_id:5f148f9264c33e389827e1fc
serialnumber:1
email:"test#gmail.com"
_id:6f148f9264c33e389827e1kc
serialnumber:2
email:"admin#gmail.com"
You can use this plugin: https://www.npmjs.com/package/mongoose-auto-increment
First you need to initialize it after creating Mongoose connection:
const connection = mongoose.createConnection("mongodb://localhost/myDatabase");
autoIncrement.initialize(connection);
Than in your subs.model.js file:
const mongoose = require('mongoose');
const autoIncrement = require('mongoose-auto-increment');
var subscriberSchema = new mongoose.Schema({
_id: {type: String, required: true},
email: {
type: String
}
}, {
versionKey: false,
collection: 'subscribers'
});
subscriberSchema.plugin(autoIncrement.plugin, {
model: 'Subscribers',
field: 'serialnumber'
});
module.exports = mongoose.model('Subscribers', subscriberSchema);

Why my mongoose request returns a query but not result data, user information in, in my case? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
I don't know why it doesn't work for me now, but it did work earlier.
I need to retrieve information from my db. I can easily save data using Model.create but when I want to get data I get:
Query {
_mongooseOptions: {},
_transforms: [],
_hooks: Kareem { _pres: Map {}, _posts: Map {} },
_executionCount: 0,
mongooseCollection: NativeCollection {
collection: Collection { s: [Object] },
Promise: [Function: Promise],
opts: {
bufferCommands: true,
capped: false,
Promise: [Function: Promise],
'$wasForceClosed': undefined
},
name: 'users',
collectionName: 'users',
conn: NativeConnection {
base: [Mongoose],
collections: [Object],
models: [Object],
config: [Object],
replica: false,
options: null,
otherDbs: [],
relatedDbs: {},
states: [Object],
_readyState: 1,
_closeCalled: false,
_hasOpened: true,
plugins: [],
_listening: false,
_connectionOptions: [Object],
client: [MongoClient],
'$initialConnection': [Promise],
_events: [Object: null prototype] {},
_eventsCount: 0,
name: 'test_name',
host: 'cocoondb-shard-00-02-qx9lu.mongodb.net',
port: 27017,
user: 'test',
pass: '1234',
db: [Db]
},
...
I have only one route and use graphql apollo server.
my express route is:
server.js (main file - enterpoint)
import confirmRoute from '../src/routes/confirm';
const app = express();
app.use('/confirm', confirmRoute);
confirm.js
import { Router } from 'express';
import SimpleCrypto from 'simple-crypto-js';
import { env } from '../../environment';
import { User } from '../models/user.model';
const secret = env.TOKEN_SECRET;
const router = Router();
router.get('/*', (req, res) => {
const crypter = new SimpleCrypto(secret);
const id = crypter.decrypt(req.url.slice(1));
const user = User.find({ id }, callback => callback);
res.status(200).send(`Hello, your email confirmed successfully : ${id}`);
})
module.exports = router;
schema
import { Schema, model } from 'mongoose';
const userSchema = new Schema({
firstname: { type: String, required: [false, 'firstname address required'] },
lastname: { type: String, required: [false, 'lastname address required'] },
email: { type: String, required: [true, 'email address required'] },
password: { type: String, required: [true, 'password required'] },
confirmed: { type: Boolean, default: false },
instagram: { type: String, default: "" },
facebook: { type: String, default: "" },
role: { type: String }
}, { timestamps: true });
export const User = model('user', userSchema, 'users');
What am I doing wrong here?
I apologise if my question is silly...
It seems you are not actually executing the query.
Please try one of this solutions to make it work.
Also I used findById, but it does not matter, you can continue to query with findOne also.
Alternative 1: then catch blocks:
router.get("/users/:id", (req, res) => {
User.findById(req.params.id)
.then(doc => {
res.send(doc);
})
.catch(err => {
console.log(err);
return res.status(500).send("something went wrong");
});
});
Alternative 2: callback
router.get("/users/:id", (req, res) => {
User.findById(req.params.id, (err, doc) => {
if (err) {
console.log(err);
return res.status(500).send("something went wrong");
}
return res.send(doc);
});
});
Alternative 3: async/await
router.get("/users/:id", async (req, res) => {
try {
let result = await User.findById(req.params.id);
res.send(result);
} catch (err) {
console.log(err);
return res.status(500).send("something went wrong");
}
});
To apply your case:
router.get("/*", (req, res) => {
const crypter = new SimpleCrypto(secret);
const id = crypter.decrypt(req.url.slice(1));
console.log("id: ", id);
User.findById(req.params.id)
.then(doc => {
console.log("doc: ", doc);
res.status(200).send(`Hello, your email confirmed successfully : ${id}`);
})
.catch(err => {
console.log(err);
return res.status(500).send("something went wrong");
});
});

Saving a document in Mongoose, reference id is not stored in the second document

When I save a new "experience" document with the model Experience, the experience _id is not saved into the document of the user. So my "experiences" array in the user document remains empty. Why?
const mongoose = require('mongoose');
const ExperienceSchema = mongoose.Schema({
name: String,
user: { type: mongoose.Schema.Types.ObjectId, ref: 'User' },
reviews: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Review' }],
categories: [{ type: String }],
});
module.exports = mongoose.model('Experience', ExperienceSchema);
==============================================
const mongoose = require('mongoose');
const UserSchema = mongoose.Schema({
name: String,
experiences: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Experience' }],
});
module.exports = mongoose.model('User', UserSchema);
=============================================
// Update experience to database
router.post('/:id', (req, res, next) => {
const idexp = req.params.id;
const newExperience = {
name: req.body.name,
user: req.user._id,
};
Experience.findOneAndUpdate({ _id: idexp }, newExperience, (err, result) => {
if (err) {
return res.render(`/${idexp}/edit`, { errors: newExperience.errors });
}
return res.redirect(`/experiences/${idexp}`);
});
});
The experiences is the sub-document of user schema. So, when you save experiences, the user will not be saved. However, when you save user, the experience should be saved.
Refer this subdocs documentation
Here is the solution... I needed to use $push to update the user document with the experience id before rendering the site.
Experience.findOneAndUpdate({ _id: idexp }, newExperience, (err, result) => {
if (err) {
return res.render('experiences/edit', { errors: newExperience.errors });
}
User.findByIdAndUpdate({ _id: req.session.passport.user._id }, { $push: { experiences: idexp } }, (err) => {
if (err) {
next(err);
} else {
return res.redirect(`/experiences/${idexp}`);
}
});
});

How to do inner reference with mongoose?

I want to do something like following code, but it failed.
var User = new Schema({
name: { type: String, required: true },
phone_number: { type: String, required: true },
modified: { type: Date, default: Date.now },
contacts: [{
user: { type : Schema.ObjectId, ref : 'User' }
}]
});
var UserModel = mongoose.model('User', User);
Is it able to achieve that purpose?
I think I used the wrong way to check it, actually it works.
Following is my test :
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
mongoose.connect('localhost', 'contacts_test');
var User = new Schema({
name: { type: String, required: true },
phone_number: { type: String, required: true },
modified: { type: Date, default: Date.now },
contacts: [
{
user: { type: Schema.ObjectId, ref: 'User' }
}
]
});
var UserModel = mongoose.model('User', User);
mongoose.connection.on('open', function () {
var user1 = new UserModel({name: 'kos', phone_number: "003"});
user1.save(function (err) {
if (err) throw err;
var user2 = new UserModel({name: 'java', phone_number: "008"});
user2.contacts = [{user: user1._id}];
user2.save(function (err) {
UserModel.findById(user2._id)
.populate('contacts.user')
.exec(function (err, user) {
if (err) console.error(err.stack || err);
console.log('user name: ' + user.name);
console.error('contact of first result : ', user.contacts[0].user.name);
mongoose.connection.db.dropDatabase(function () {
mongoose.connection.close();
});
});
});
});
});