Creating unique index via mongodb native driver - node.js

There is a code:
const { MongoClient } = require('mongodb')
const db = MongoClient.connect('mongodb://172.17.0.2:27017/test')
db
.then(
async dataBase => {
eduDb = dataBase.db('edu-service-accounts')
const accounts = eduDb.collection('accounts')
await accounts.createIndex({ email: 1 }, { unique: true })
accounts.insertOne({ email: '123' })
}
)
Code above creates an index, but that is no unique. I already read official docs for native mongoDB driver, but can't handle it.
And yes, I've deleted all old indexex before testing that code.
Can someone please show a code that really create an index with unique.
I mean not part of official doc, or something like that - I need code that works.
NOTE: I tested that code with local db and mlab - the same result.

Like the documentation says: db.createIndex(collectionname, index[, options], callback) the creation returns an index. Try to log the result of the callback. Maybe you are getting an error from the db.
Try something like:
// your connection stuff
accounts.createIndex({ email: 1 }, { unique: true }, function(err, result) {
if(err) {
console.log(err);
} else {
console.log(result);
}
});
After that please provide us the logs.

Related

How to save cloudinary url to mongoDb

I'm trying to save Cloudinary url to MongoDB but really don't know what is wrong with my code, because it's not working.
here is my code :
exports.test = asyncHandler(async (req, res, next) => {
const email = req.params.email;
console.log
cloudinary.uploader
.upload(req.file.path, { folder: 'avatar' })
.then((result) => {
console.log(result);// shows correctly on console
const { secure_url, public_id } = result;
console.log('url:',secure_url)// url & secure_url shows correctly on console
console.log('public_url:',public_id);
Resume.findOneAndUpdate(
{
email:email,
},
{ $set: { imagePath: secure_url} },
{
new: true,
fields: {
imagePath: 1,
},
}
);
console.log('upload successful!!');
})
.catch((error) => {
console.log(error);
});
});
I use $set because I want the field created if it didn't exist before. Also, I get the public_id and secure_url successfully from Cloudinary, but it didn't save in my database.
here is the output from console.log(result):
{
asset_id: '1ee919b68e258c9778097e40671ac710',
public_id: 'seawedkarowxgnipz8hq',
url: 'http://res.cloudinary.com/workaman/image/upload/v1656322947/seawedkarowxgnipz8hq.png',
secure_url: 'https://res.cloudinary.com/workaman/image/upload/v1656322947/seawedkarowxgnipz8hq.png',
original_filename: 'file_cuyajt',
}
and here is how i defined the model:
const ResumeSchema = new mongoose.Schema({
imagePath:{
type:String,
required:false
},
cloudinary_Id:{
type:String,
required:false
},
})
It seems I'm missing out on something but I really can't figure it out. when I submit from the frontend, I get the message "console.log('upload successfully!!')" but nothing is saved.
I think the issue here is that you're mixing up the MongoDB Node.js SDK with Mongoose a little bit. In the code that you shared you have both ResumeSchema and Resume - just check that those are correct.
In Mongoose the findOneAndUpdate() method does not have a $set option. The MongoDB CLI and subsequently their Node.js Driver also has findOneAndUpdate(), but the signature of that function and it's usage options somewhat differ.
Without seeing the rest of your code it's hard to tell what is exactly going on but my gut feeling is that you've mixed up these two methods. I hope this helps.

Mongoose can't search by number field

I have a schema that has an id field that is set to a string. When I use collection.find({id: somenumber}) it returns nothing.
I've tried casting somenumber to a string and to a number. I've tried sending somenumber through as a regex. I've tried putting id in quotes and bare... I have no idea what's going on. Any help and input would be appreciated.
Toys.js
var Schema = mongoose.Schema;
var toySchema = new Schema( {
id: {type: String, required: true, unique: true},
name: {type: String, required: true},
price: Number
} );
My index.js is as such
app.use('/findToy', (req, res) => {
let query = {};
if (req.query.id)
query.id = req.query.id;
console.log(query);
// I've tried using the query variable and explicitly stating the object as below. Neither works.
Toy.find({id: '123'}, (err, toy) => {
if (!err) {
console.log("i'm right here, no errors and nothing in the query");
res.json(toy);
}
else {
console.log(err);
res.json({})
}
})
I know that there is a Toy in my mongoDB instance with id: '123'. If I do Toy.find() it returns:
[{"_id":"5bb7d8e4a620efb05cb407d2","id":"123","name":"Dog chew toy","price":10.99},
{"_id":"5bb7d8f7a620efb05cb407d3","id":"456","name":"Dog pillow","price":25.99}]
I'm at a complete loss, really.
This is what you're looking for. Visit the link for references, but here's a little snippet.
For the sake of this example, let's have a static id, even though Mongo creates a dynamic one [ _id ]. Maybe that what is the problem here. If you already a record in your DB with that id, there's no need for adding it manually, especially not the already existing one. Anyways, Drop your DB collection, and try out this simple example:
// Search by ObjectId
const id = "123";
ToyModel.findById(id, (err, user) => {
if(err) {
// Handle your error here
} else {
// If that 'toy' was found do whatever you want with it :)
}
});
Also, a very similar API is findOne.
ToyModel.findOne({_id: id}, function (err, toy) { ... });

CosmosDB + MongoAPI, updating document workaround?

I've been trying to simply update a CosmosDB document via the mongodb api in my node application, I've been testing in and out, no errors but the value does not update no matter what.
I know updating array elements is not supported which is fine, but this is a top-level key-value pair. Changes simply don't happen with no error whatsoever.
I've been following the Mean.js project with uses CosmosDB + Mongoose + Node + Angular, looking at the API for updating hero and trying some of that code but it still doesn't update.
I've been reading the documentation trying to figure out the default way of handling CRUD operations within CosmosDB and which parts of the MongoAPI it supports but so far no luck.
For tests purposes, I'm using this code:
async function updateUser(id) {
try {
let user = await User.findById(id);
console.log (id);
console.log(user);
if (!user) return
user.id = id
user.firstName = 'ASDASDASASDASDASDASDASDA'
const result = await user.save()
console.log(result);
}
catch(err) {
console.log("There was an error updating user", err);
}
}
So, I've been playing around some more and managed to update a hero using this code:
updateHero('10')
async function updateHero(id) {
const originalHero = {
uid: id,
name: 'Hero2',
saying: 'nothing'
};
Hero.findOne({ uid: id }, (error, hero) => {
hero.name = originalHero.name;
hero.saying = originalHero.saying;
hero.save(error => {
return(hero);
console.log('Hero updated successfully!');
});
});
}
Now I'm just not sure why this has actually worked and why it hasn't before. The main thing that is different is that I'm using an 'uid' instead of the actual ID assigned by CosmosDB.
I tested sample code you provided and they both updated document successfully.
Sample document:
Snippet One:
updateUser('5b46eb0ee1a2f12ea0af307f')
async function updateUser(id) {
try {
let user = await Family.findById(id);
console.log (id);
console.log(user);
if (!user) return
user.id = id
user.name = 'ASDASDASASDASDASDASDASDA'
const result = await user.save()
console.log(result);
}
catch(err) {
console.log("There was an error updating user", err);
}
}
Output One:
Snippet Two:
updateFamily('5b46eb0ee1a2f12ea0af307f')
async function updateFamily(id) {
const updateFamily = {
_id: id,
name: 'ABCD',
};
Family.findOne({ _id : id }, (error, family) => {
family.name = updateFamily.name;
family.save(error => {
console.log(JSON.stringify(family));
console.log('Hero updated successfully!');
return(family);
});
});
}
Output Two:
In addition, you could use db.collection.update() to update document.
db.families.update(
{ _id: '5b46eb0ee1a2f12ea0af307f' },{ $set:
{
name: 'AAAA'
}
})
More details,please refer to the doc: https://docs.mongodb.com/manual/reference/method/db.collection.update/
Hope it helps you.

How do I remove a document with node-mongodb-native driver?

The operation returns saying deleted: 0
const res = await ctx.db.collection(this.col).removeOne({ _id: ctx.params.id });
Not sure what I'm doing wrong here. GET requests by the { _id: <id> } seem to work fine.
ctx.params.id is defined and is the same as the ObjectId in the database.
According to this doc you can do collection.removeOne() (see example 2) https://mongodb.github.io/node-mongodb-native/2.2/api/Collection.html#remove
// Remove all the document
collection.removeOne({a:1}, {w:1}, function(err, r) {
test.equal(null, err);
test.equal(1, r.result.n);
db.close();
});
Try casting ctx.params.id to ObjectId, which is how mongodb stores identifiers internally.
import { ObjectId } from 'mongodb'
id = ObjectId(ctx.params.id)

Update data in MongoDB with Mongojs using findAndModify()

Yet another first-timer problem here. This gets data from a database and displays it in some text fields (that part is not shown in the code below) and after the user edits it the data should be updated in the database via the findAndModify() method and I think this is where the issue lies. There are no errors, it just doesn't do anything. EDIT The following error is received: MongoError: Either an update or remove=true must be specified
server.js
MongoClient.connect("mongodb://user:secretPassword#aws-us-east-1-portal.7.dblayer.com:10712,aws-us-east-1-portal.10.dblayer.com:10316/database", function(err, db) {
if (err) throw err;
var contactList = db.collection("contactList");
app.put('/contactList/:id', function(req, res) {
var id = req.params.id;
console.log("edited: " + req.body.name); //works up until here
contactList.findAndModify({
query: {_id: mongojs.ObjectId(id)},
update: {$set: {name: req.body.name, email: req.body.email, number: req.body.number}},
new: true
}, function (err, doc) {
res.json(doc);
})
});
controller.js
$scope.update = function() {
$http.put('/contactList/' + $scope.contact._id, $scope.contact).success(function(response) {
refresh();
})
};
If this were me I would first do a couple of things:
Before your call to findAndModify just do a simple find using your query. Make sure you can actually find the object using your query. If that works you know that the 'find' part of the findAndModify is probably ok.
Do some console logging inside the callback handler of the findAndModify call. As it stands you do not do anything if an err is returned from the findAndModify call. It is possible your call is returning an error that you are just ignoring and it may provide some additional insight into your problem.
I would try these two first and see if it helps.
Update:
Example using native:
collection.findAndModify(
{ field: 'some value' },
[],
{ $set: { field2: 'some new value' } },
{ new:true },
function(err, doc) {
//handle err and doc
});

Resources