subsub document id returns whole document - mongodb

When I findOne based on deliverables.steps._id it's returning my entire document rather than just my step with the particular id. Can I not have it return my individual step rather than the whole document? The reason I ask is so when I need to update I just update this step rather than updating the whole document each time.
exports.findStep = function(req, res) {
Project.findOne({'deliverables.steps._id': req.params.stepId}).sort('-created').exec(function(err, step) {
if (err) {
return res.status(400).send({
message: errorHandler.getErrorMessage(err)
});
} else {
res.jsonp(step);
}
});
};

Related

Latency compensation and Firestore transactions

I have an onSnapshot keeping track of the documents in a collection:
db.collection('/.../').onSnapshot(querySnapshot=> mylocalvariable = querySnapshot.docs)
Now, I want to select the first (in some order) element of this collection of documents that my user has not yet handled. When a user is done handling a document, I use a transaction to update the document according to the user's needs (transaction is better for me than .update() because I might have multiple users changing different parts of the document).
The problem is that unlike a .update (which would update mylocalvariable immediately), it seems like the transaction finishes without updating mylocalvariable. So, when I go to grab the "next" document, it just grabs the same document, because the function runs before the variable gets updated.
Code sample:
db.collection('/mycollection').onSnapshot(querySnapshot=> mylocalvariable = querySnapshot.docs)
function selectnextrecord(){
nextrecord = mylocalvariable.find(x=>!x.data().done)
console.log(nextrecord)
//expected: Get something different than the current record
//observed: This is being run with old data, so it returns the same record that I currently have with the old data.
}
let nextrecord;
selectnextrecord();
function submitchanges(){
let sfDocRef = db.collection('/mycollection').doc(nextrecord.id);
return db.runTransaction(function(transaction) {
return transaction.get(sfDocRef).then(function(sfDoc) {
if (!sfDoc.exists) {
throw "Document does not exist!";
}
transaction.update(sfDocRef, {done:true});
});
}).then(function() {
selectnextrecord();
}).catch(function(error) {
console.log("Transaction failed: ", error);
});
}```
After going through the documentation, I think this is expected behavior.
Do not modify application state inside of your transaction functions. Doing so will introduce concurrency issues, because transaction functions can run multiple times and are not guaranteed to run on the UI thread. Instead, pass information you need out of your transaction functions
In any case, you could filter the documents that are not done with .where() and then place your transaction inside a foreach:
db.collection('cities')
.where("done", "==", true)
.get()
.then(snapshot => {
snapshot.forEach(doc => {
return db.runTransaction(function(transaction) {
return transaction.get(sfDocRef).then(function(sfDoc) {
if (!sfDoc.exists) {
throw "Document does not exist!";
}
transaction.update(sfDocRef, {done:true});
});
}).catch(function(error) {
console.log("Transaction failed: ", error);
});
})
})

Mongoose findOneAndUpdate return not updated model

I've 1 little issue. I'm trying update model by findOneAndUpdate method. And this method works unexpected - method update model in DB but return old model (before update)
try {
const updatedLanding = await Landing.findOneAndUpdate({key: req.body.key}, {
$set: {
name: req.body.name,
}
},
).exec((err, result) => {
if (err) {
res.status(422).send({error: err});
return
}
res.send({response: result})
});
}
catch (e) {
res.status(400).send(e)
}
in mongoose query, findOneAndUpdate returns the old record that has been updated, not the updated record, the record has actually been updated, but you can not get the updated result as the query returns the old one by default, if you want to see the updated record you have to issue another query to find the record and get its updated data.
If you update document using findOneAndUpdate() hook, you'll get the old document unless you specify
{ new: true }

In mongo how to get the current position of the record in the table with the total records for pagination?

I'm trying to return create a paginated list. I used graphql to query the data. With my query, I pass the number of records I need (In a variable named first) and the ID of the last fetched record (In a varible called after). Now I managed to write a query (Note that I used mongoose) to fetch the records. Now what I need to do is get the relavant information to perform the pagination like hasNextPage, hasPreviousPage, currentPage and totalPages.
To get most of these information I need to get the total number of records in the database. To do that I need to send another db request.
I also need to know the position of the record in the table. No idea how.
Here's the query:
new Promise((resolve, reject) =>
Company.where('_id')
.gt(after)
.limit(first)
.lean()
.exec((error, doc) => {
if (error) {
reject(error);
}
resolve({
edges: doc,
pageInfo: {
hasNextPage: '...',
hasPreviousPage: '...',
currentPage: '...',
totalPages: '...'
}
});
}))
Any idea how to do this efficiently?
you can try this module mongoose-paginate
here what i uses, for pagination,
var current = req.query.filter.current;
var limit = req.query.filter.limit;
console.log('params.query.filter.current',current);
var skip = Number(limit)*Number(current)-Number(limit);
console.log('skip::',skip);
Cours.find({'attributes.version.status': true}).skip(skip).limit(limit).sort({_id:'asc'}).exec(function (err, resulta) {
if (err) {
console.log('erreur trouverCours');
res.json({
protecteds: err
});
}
console.log('cours ::', resulta);
res.json({
"data": resulta
});
});

Unable to enter data in mongo database in express

router.get('/wiki/:topicname', function(req, res, next) {
var topicname = req.params.topicname;
console.log(topicname);
summary.wikitext(topicname, function(err, result) {
if (err) {
return res.send(err);
}
if (!result) {
return res.send('No article found');
}
$ = cheerio.load(result);
var db = req.db;
var collection = db.get('try1');
collection.insert({ "topicname" : topicname, "content": result }, function (err, doc){
if (err) {
// If it failed, return error
res.send("There was a problem adding the information to the database.");
}
else {
// And forward to success page
res.send("Added succesfully");
}
});
});
Using this code, I am trying to add the fetched content from Wikipedia in to the collection try1. The message "Added succesfully" is displayed. But the collection seems to be empty. The data is not inserted in the database
The data must be there, mongodb has { w: 1, j: true } write concern options by default so its only returns without an error if the document is truly inserted if there were any document to insert.
Things you should consider:
-Do NOT use insert function, its depricated use insertOne, insertMany or bulkWrite. ref.: http://mongodb.github.io/node-mongodb-native/2.1/api/Collection.html#insert
-The insert methods callback has two parameters. Error if there was an error, and result. The result object has several properties with could be used for after insert result testing like: result.insertedCount will return the number of inserted documents.
So according to these in your code you only test for error but you can insert zero documents without an error.
Also its not clear to me where do you get your database name from. Is the following correct in your code? Are you sure you are connected to the database you want to use?
var db = req.db;
Also you don't have to enclose your property names with " in your insert method. The insert should look something like this:
col.insertOne({topicname : topicname, content: result}, function(err, r) {
if (err){
console.log(err);
} else {
console.log(r.insertedCount);
}
});
Start your mongod server in a correct path,i.e, same path as that of what you are using to check the contents of collection.
sudo mongod --dbpath <actual-path>

Update MongoDB object field with _assign/_merge/_extend

I am running into a question when to use which one, the following is update function for mongoose, it works fine.
// Updates an existing form in the DB.
exports.update = function(req, res) {
if(req.body._id) { delete req.body._id; }
Form.findById(req.params.id, function (err, form) {
if (err) { return handleError(res, err); }
if(!form) { return res.send(404); }
var updated = _.assign(form, req.body);
updated.formContent = req.body.formContent;
updated.save(function (err) {
if (err) { return handleError(res, err); }
return res.json(200, form);
});
});
};
Tried the following to replace the form data.
_.assign(form, req.body); // Works (update database)
_.merge(form, req.body); // Not Work (database not updating, remain the same)
_.extend(form, req.body); // Works (update database)
The above result show merge doesn't work when there is object within the post data.
Could some please explain why one is not working the others is ok. I have read the following question
Lodash - difference between .extend() / .assign() and .merge()
but i am curious to understanding which one won't update the database, but when applied with assign and extend it's working.