Add new property to a document in DocumentDB with nodejs - node.js

I have a JSON document in DocumentDB.
I wish to add new data to a given document.
For example.
Current document:
{
"User": "ABC",
"UserID": "123"
}
New document
{
"User": "ABC",
"Height":"1.60",
"UserID": "123"
}
I have tried solutions such as mentioned here:
Add new properties to DocumentDB Document in Stored procedure
But I get "getContext is not defined".
I believe the issue is that I am unsure of how to call a document via a function.
I would like:
var documentURL = "dbs/'dbname'/colls/'collsname'/docs/'docsname'"
editDocument(documentURL)
function editDocument(document) {
var collection = getContext().getCollection();
var response = getContext().getResponse();
document.Height = "1.60";
collection.createDocument(collection.getSelfLink(), document, function(err, result) {
if(err) throw err;
// Return the resulting document back as the response.
response.setBody(result);
});
}
Should I use client.replaceDocument instead, or maybe there is a better way to do this.
The issue may be that the function is plainly trying to use the text location "dbs/colls/docs" in the function rather than the document itself.
Thanks for any help in advance!

Yes, you need to use replaceDocument instead.
var documentURL = "dbs/'dbname'/colls/'collsname'/docs/'docid'"
client.readDocument(documentURL, (err, doc) => {
if(err) return console.log(err);
doc.Height = "1.60";
client.replaceDocument(documentUrl, doc, (err, result) => {
if(err) return console.log(err);
console.log('replaced document');
});
});

Related

Unable to delete a document with passed "email" and "_id" anyhow

I wanted to delete a document with concerned _id and email when I click on "Remove task" in the HTML file.
Following is the code which removes that task:
I've passed value of email and _id(only hexadcemial string value) to the code:
collection.findOneAndDelete({email:email,_id:taskid},function (err, result) {
if (err) {
console.log(err);
} else {
console.log("Removed!");
console.log(result);
callback(result);
}
db.close();
});
But, the function is not recognizing _id that I've passed. The value of "taskid" variable is 566836bd8db43d3d56e23a4a i.e. only strings value from _id:
ObjectId("566836bd8db43d3d56e23a4a")
var taskid=566836bd8db43d3d56e23a4a;
I've tried every possible declaration of taskid to convert it so that the function could recognize the value of _id and match it:
var taskid= "ObjectId("+'"'+req.param('taskid')+'"'+")";
But till now, I am not able to match the _id with the taskid. Any fix?
if you are going to compare with ObjectId then
var ObjectId = require('mongoose').Types.ObjectId
collection.findOneAndDelete({email:email,_id:new ObjectId(taskid)},function (err, result) {
if (err) {
console.log(err);
} else {
console.log("Removed!");
console.log(result);
callback(result);
}
db.close();
});
Should work for you.
If you feel the job too hard for each and every query then you can create an new method.
String.prototype.toObjectId = function() {
var ObjectId = (require('mongoose').Types.ObjectId);
return new ObjectId(this.toString());
};
// Every String can be casted in ObjectId now
console.log('545f489dea12346454ae793b'.toObjectId());

How do I update a doc in Cloudant using Cloudant Node.js

So, what I'm doing should be really simple, and maybe it is and I'm just doing something wrong. I want to update an existing document in my database but I'm having some issues, can someone please advise?
Nano's Documentation states the following for insert:
db.insert(doc, [params], [callback])
Therefore, I should surely be able to do the following:
var user = {
'firstname' : 'my',
'secondname' : 'name'
};
db.insert(user, {_rev: '2-cc5825485a9b2f66d79b8a849e162g2f'}, function(err, body) {});
However, whenever I try this, it creates an entirely new document. If I do the following then it will indeed update my document, but of course, with nothing in this document other than the _rev:
db.insert({_rev: '2-cc5825485a9b2f66d79b8a849e162g2f'}, function(err, body) {});
So the question is, how do I pass in my object and get it to update, rather than creating a new record?
var user = {
'firstname' : 'my',
'secondname' : 'name',
'_id': <id from prev object>,
'_rev': <rev from prev object>
};
db.insert(user, function(err, body) {});
the _id and _rev are both required in order for the update to work.
they should be in the object that you are sending also.
The first argument in the db.insert(...) command is the document which you want to create/update. If you pass in a doc with a ._rev attribute, then it will replace the document with that same _rev in Cloudant with the doc passed in as the first argument of your db.insert(...). If the doc does not include a ._rev attribute, then Cloudant will create an entirely new document.
This explains the behavior you were experiencing in both the scenarios you tried. In order to make an update to your doc, make sure to include ._id and ._rev attributes, along with the rest of your doc's attributes when you use it as the first argument to your db.insert(...) function.
Got it! Here's the solution:
db.get('user', { revs_info: true }, function(err, doc) {
if (!err) {
console.log(doc);
doc.firstname = 'my';
doc.secondname = 'name';
db.insert(doc, doc.id, function(err, doc) {
if(err) {
console.log('Error inserting data\n'+err);
return 500;
}
return 200;
});
}
});
First get the record id and rev id (_id,_rev)
const newData={email:"aftabfalak956#gmail.com",name:"Aftab Falak"}
cloudant.use("user").find({selector:{_id:"user_id"}}, (err, documents) => {
var revision = documents.docs[0]._rev;
const data={...documents.docs[0],...newData};
cloudant.use("user").insert(data,{_rev:revision},function(err){
if (!err) {
console.log('success', 'The record was updated successfully');
}
else {
console.log('failure', err);
}
});
});

MongoDB two same records

I'm doing a project which is backed by Nodejs and MongoDB. I am quite new to MongoDB and I am lacking a clue why I quite often(almost always) get two same records in collections when I do posts. The two records only differ by ID, which are for example ObjectId("53aefb0fc68a0810504d2066") and 53aefb0fc68a0810504d2066, is this normal or am I doing something wrong? Thanks for any pointers.
Here is some node code:
server.js:
app.post("/:collection", function (req, res) {
var object = req.body;
var collection = req.params.collection;
collectionDriver.save(collection, object, function (err, docs) {
if (err) {
res.send(400, [err, object]);
} else {
res.send(201, docs);
}
});
});
collectionDriver:
save: function(collectionName, obj, callback) {
this.getCollection(collectionName, function(error, the_collection) {
if( error ) callback(error);
else {
obj.created_at = new Date();
the_collection.insert(obj, function() {
callback(null, obj);
});
}
});
},
getCollection: function(collectionName, callback) {
this.db.collection(collectionName, function(error, data) {
if (error) {
callback(error);
} else {
callback(null, data);
}
});
},
Everytime you ask MongoDB to save an object without an _id field, it automatically generates a new, globally unique ObjectID for that field and saves the object under that ObjectID.
When you want to use save to update an existing document, you need to make sure that the _id field is populated with the _id of the document you want to update.
Alternatively, you can create an unique index on those fields you consider relevant for determining what's a duplicate and what isn't. However, in that case an attempt to save an already existing document will throw an error instead of replacing the document.

How to query the CouchDB data with the start date and end date

In my node application I am using the Cradle library to save the data in CouchDB.
Now I want to get the stored data with the specified start date and end date.
How can I do this. I have added design document as below. Is it correct?
How to pass my parameters to this function?
function (doc) {
if (doc.date) {
var key = [doc.start, doc.end];
emit(key, doc);
}
}
Document Structure
{
"_id": "58113f948561d38b1eba8ba343432c45",
"_rev": "1-be4f3d2fd93a8941659c73333941561d",
"date": "2013-04-29T06:36:29.165Z",
"name":"sdasd",
"age":"20"
}
I'm querying like below for the above design document
var startDate = '2013-04-27T08:41:23.559Z';
var endDate = '2013-04-29T08:41:23.559Z';
db.view('data/byDate', { key: [startDate, endDate] }, function(err, doc) {
if (!err) {
console.log(doc.length);
} else {
console.log('Error '+err);
}
});
The structure of your example document and your view do not match: You try to emit doc.start and doc.end but these fields are not present (hence the document will not be included in the view). Maybe you just want to emit doc.date? Like so:
function (doc) {
if (doc.date) {
emit(doc.date, doc);
}
}

find results of attributes in mongodb are always undefined

I really really need help in this. I am using node.js with mongodb and mongoose. So far I've managed to create a schema and save those into my database.
var Bericht = new Schema({
name : String
, mail : String
, betreff : String
, inhalt : String
, datum : Date
});
var Bericht = mongoose.model('Bericht', Bericht);
I habe a html formular where I can transmit with misc. fields data, by querystring I converting those into readable strings
var bericht_data = {
name: tempo.Name
, mail: tempo.Mail
, betreff: tempo.Betreff
, inhalt: tempo.Inhalt
};
var testoro = new Bericht(bericht_data);
testoro.save(function (err) {
if (!err) console.log('Success!');
});
so tempo.Name for example is a string and it also successful in saving it.
So far I can save all data from this formular into my mongodb.
Now the very problem: I want the data back as string to handle for dynamic html.
To get the info into my console, I use
Bericht.find(
{},
{ '_id': 0},
function(err, docs) {
if (!err){
console.log(docs);
// process.exit();
}
else { throw err;}
}
);
The console gives me all data which was ever saved in my schema Bericht excluding the long _id stuff. Sample output:
[ { name: 'Hans', mail: 'hans#wurst.de', betreff: 'I lost my wurst', inhalt: 'look at me, I am amazing' } ]
That's just one, normally there would be a huge amount of data.
The idea is right now to extract only the name into a string like "Hans". I want to get this name into a var, but hell it seems impossible!
I've tried
Bericht.find(
{},
{ '_id': 0},
function(err, docs) {
if (!err){
console.log(docs.name);
// process.exit();
}
else { throw err;}
}
);
But the I get only "undefined" delivered. I appreciate your help!
Take a look at Mongoose QueryStreams. I haven't used it myself, but I've modified their example code to fit your Model, to give you an idea of how it might work in practice:
var stream = Bericht.find().stream()
, names = []
, i;
function closeHandler() {
console.log(JSON.stringify(names));
};
stream.on('data', function (doc) {
if (doc.name) {
names.push(doc.name);
}
})
stream.on('error', function (err) {
// handle err
})
stream.on('close', closeHandler)
Mongoose find return an array of documents so you should try the following:
Bericht.find(
{},
{ '_id': 0},
function(err, docs) {
if (!err){
for(var i=0; i<docs.length; i++)
{
console.log(docs[i].name);
}
// process.exit();
}
else { throw err;}
}
);

Resources