I have a little trouble: I'm just trying to insert the list of raw records into mongodb collection right after I cleaned it. But I don't receive any feedback from insert method. This is my code:
model.collection.remove((removeError, removeResult) => {
console.log('remove cb');
model.collection.insert(seeds, (insertError, insertedRecords) => {
console.log('insert cb');
});
});
Actually I wanted to do this by using the mongoose API(model is the mongoose model) but on my way of exploring this problem I figured out that the native driver don't execute this as well.
That's what I have trying to use mongoose wrappers:
model.remove({}, (err, docs) => {
if (err) {
console.log('remove error');
} else {
console.log('remove success');
model.insertMany(seeds, (insertError, insertedRecords) => {
if (insertError) {
console.log('insert error');
} else {
console.log('insert success');
}
});
}
});
When I run this script I see 'remove success' and that's all. And if I comment out the removing process then 'insert success' is displayed
My mongoose model is really simple:
const schema = new Schema({
name: {type: String, unique: true, index: true},
});
seeds variable:
export default [
{name: 'USA'},
{name: 'Germany'},
{name: 'France'}, ...
Please explain me where am I wrong or what I don't understand
UPD
I have tried this using the MongoClient and it works!
MongoClient.connect(url, function(err, db) {
const collection = db.collection('countries');
collection.deleteMany({}, (err, r) => {
console.log('delete', err);
collection.insertMany(seeds, (err, r) => {
console.log('insert', err);
db.close();
Country.find({}, function (err, res) {
console.log(res);
});
});
});
});
So problem is in the mongoose. Though actually I thought {ModelName}.collection is the native driver
To clear up your confusion, this line model.collection.remove((removeError, removeResult) is wrong.
The syntax for remove is this, db.collection.remove(
<query>,
<justOne>
)
there is no query , but here model.remove({}, (err, docs) => { you do have query({}) which means delete all.
examine this statement db.mycol.remove({'title':'MongoDB Overview'}) which is a query to find and delete any document with a title of MongoDB Overview.
Does any of this makes sense?
Related
I am trying to remove one object from the User collection like this
router.post('/accept-trades', function (req, res, next) {
const {senderName, receiverName, senderId} = req.body;
const user = req.user;
console.log(senderName, receiverName);
if (senderName) {
User.findOne({ name: senderName })
.then(sender => {
_.remove(user.receivedTradeRequest, {username: senderName});
_.remove(sender.sentTradeRequest, {username: receiverName});
console.log('user.receivedTradeRequest', user.receivedTradeRequest);
console.log('\n\nuser.sentTradeRequest', user.sentTradeRequest);
async.parallel([
function (cb) {
user.save()
.then(isSave => {
cb(null, true);
})
.catch(err => {
cb(err, null);
});
},
function (cb) {
sender.save()
.then(isSave => {
cb(null, true);
})
.catch(err => {
cb(err, null);
});
}
], (err, results) => {
if (err) {
return res.status(500).json({
message: 'Error: Trade is invalid as Card is already traded!',
});
}
res.send('done');
//res.redirect('/trade');
});
})
.catch(err => {
throw err;
});
} else {
return res.status(500).json({
message: 'Only accessible to logged in users!',
});
}
});
Here, user is accessed by req.user (i'm using passport).
When i log the user after removal, user.receivedTradeRequest and sender.sentTradeRequest printing empty array which is the correct behaviour.
But when i see the mongodb the array still present for the username.
Could you please suggest what is wrong with the code ?
PS: I know about the mongodb $pull for removal. I am doing some other computation on the user data so had to do with above approach.
I was able to solve it by re-assigning the array after removing the element. Used _.filter instead of _.remove solves the problem.
One thing i don;t understand is the lodash _.remove update the original array after deletion but that clearly is not the case here.
I've been working on a website with a search feature which matches the queries with the various article present in MongoDB. currently mongoDB does not support fuzzy search with is what I want with my search feature. For that I've found that Elasticsearch works the best with this type of problem. I've use mongoosastic client for the node.js for this purpose. I was able to save data item and search the query but it can't search if there is any spelling mistake present in it. How can I customise the query that help finding the text even with some typo or word missing.
const mongoose = require('mongoose');
const mongoosastic = require('mongoosastic');
mongoose.connect('mongodb://localhost:27017/mongosync');
var UserSchema = new mongoose.Schema({
name: String
, email: String
, city: String
});
UserSchema.plugin(mongoosastic, {
"host": "localhost",
"port": 9200
}, {hydrate:true, hydrateOptions: {lean: true}});
var User = mongoose.model('user', UserSchema);
// User.createMapping((err, mapping) => {
// console.log('mapping created');
// });
// var newUser = new User({
// name: 'Abhishek',
// email: 'abhishek.patel#company.com',
// city: 'bhopal'
// });
// newUser.save((err) => {
// if(err) {
// console.log(err);
// }
// console.log('user added in both the databases');
// })
// newUser.on('es-indexed', (err, result) => {
// console.log('indexed to elastic search');
// });
User.search(
{query_string: {query: "abheshek"}},
function(err, results) {
if(err){
console.log('ERROR OCCURED');
} else {
console.log(results);
}
});
I think this will help :)
Place.search({
match: {
name: {
query: q,
fuzziness: "auto"
}
}
}, (err, results) => {
if (err) return next(err);
const data = results.hits.hits.map(hit => hit);
// return res.json(data);
return res.status(200).json({locations: data});
});
I'm trying to update the subdocument within the array without success. The new data doesn't get saved.
Express:
router.put('/:id/:bookid', (req, res) => {
library.findOneAndUpdate(
{ "_id": req.params.id, "books._id": req.params.bookid},
{
"$set": {
"title.$": 'new title'
}
}
});
LibraryScema:
const LibarySchema = new Library({
Name: {
type: String,
required: false
},
books: [BookSchema]
});
bookScema:
const BookSchema = new Schema({
title: {
type: String,
required: false
},
Chapters: [
{
chapterTitle: {
type: String,
required: false
}
}
]
});
I only aim to update the sub-document, not parent- and sub-document at same time.
I had a similar issue. I believe there is something wrong with the $set when it comes to nested arrays (There was an entire issue thread on GitHub). This is how I solved my issue.
var p = req.params;
var b = req.body;
Account.findById(req.user._id, function (err, acc) {
if (err) {
console.log(err);
} else {
acc.websites.set(req.params._id, req.body.url); //This solved it for me
acc.save((err, webs) => {
if (err) {
console.log(err);
} else {
console.log('all good');
res.redirect('/websites');
}
});
}
});
I have a user with a nested array.
Try this code
router.put('/:id/:bookid', (req, res) => {
library.findById(
req.params.id, (err, obj) => {
if (err) console.log(err); // Debugging
obj.books.set(req.params.bookid, {
"title": 'new title',
'Chapters': 'your chapters array'
});
obj.save((err,obj)=>{
if(err) console.log(err); // Debugging
else {
console.log(obj); // See if the saved object is what expected;
res.redirect('...') // Do smth here
}
})
})
});
Let me know if it works, and I'll add explanation.
Explanation: You start by finding the right object (library in this case), then you find the correct object in the array called books.
Using .set you set the whole object to the new state. You'll need to take the data that's not changing from a previous instance of the library object.
I believe this way will overwrite and remove any data that's not passed into the .set() method. And then you save() the changed.
I've been doing some research within these couple of days but got stuck while trying to test the codes that I got from the web.
var MongoClient = require('mongodb').MongoClient,
format = require('util').format;
MongoClient.connect('mongodb://127.0.0.1:27017/test', function(err, db) {
if (err) {
throw err;
} else {
console.log("successfully connected to the database");
db.collection('chat', function(err, collection) {
collection.find({}, {
tailable: true,
awaitdata: true,
numberOfRetries: -1
})
.sort({
$natural: 1
})
.each(function(err, doc) {
console.log(doc);
})
});
}
db.close();
});
And the error is:
c:\Project\node_modules\mongodb\lib\mongo_client.js:406
throw err
^
Am I missing any external library/reference because the error says "Cannot read property 'find' of undefined".
mongodb version: "2.0.31"
You check for a possible error in your first callback, but not the second one. Instead of
db.collection('chat', function(err, collection) {
collection.find({}, {...
Try:
db.collection('chat', function(err, collection) {
if (err) {
throw err;
} else {
collection.find({}, {...
This won't make your code snippet do what you want, but it will let you find out what error is preventing it from working.
You didnt export the collection module correctly....
If suppose your model class is collection.js,
then at the end of the class, it should be
module.exports = { Collection}
Final code will look like,
const mongoose = require('mongoose')
var Collection = mongoose.model('Collection', {
a: {type: String},
b: {type: String},
c: {type: Number},
}
module.exports = { Collection}
You can also do it like this:
collection.find((err, data) => {
if (err) {
console.log("An error: ", err);
} else {
console.log("My data", data);
}
});
a quick one:
Why is Mongoose change/upgrading the _id field of a document when I push an update?
Is this an intended behavior?
Thanks.
This is the update I use inside my PUT route, and it returns successfully the updated model, but unfortunately with a new _id for doc
Document.findById(req.params.doc_id, function (err, doc) {
if (err)
res.send(err)
// Do some subdoc stuff here …
doc.save(function (err) {
if (!err) {
console.log('Success!');
res.json(doc);
} else {
console.log(err);
}
});
});
Okay, problem solved:
I was logging the wrong _id (doh!)
Mongoose docs http://mongoosejs.com/docs/2.7.x/docs/model-definition.html
suggest using update or findOne
ex:
var query = { name: 'borne' };
Document.update({"_id": req.params.doc_id}, { name: 'jason borne' }, {}, function(err, numAffected){
if (!err) {
console.log('Success!');
res.json(numAffected);
} else {
console.log(err);
}
});
or
Model.findOne({ "_id": req.params.doc_id }, function (err, doc){
doc.name = 'jason borne';
doc.save();
// here you could use your save instead, but try not to use the doc again
// it is confusing
// doc.save(function (err, documentSaved, numberAffected) {
// if (!err) {
// console.log('Success!');
// res.json(documentSaved);
// } else {
// console.log(err);
// }
// });
});
Later I also found the findById update suggested in some docs http://mongoosejs.com/docs/documents.html, which seems to be up to date, check the version you are using and also double check the two times you are using doc in your functions here. Also you can check your mongoDB and see if there are more than one record getting saved.
db.documents.find( {} )