selecting from couchdb in nodejs craddle? - node.js

I have couchdb and document my_users whitch looks like:
_id
password
email
...
how can I select _id for _id and password.
I would like sth like mysql select _id from my_users where _id = "mylogin" and password = "mypassword"
i using cradle
and trying sth like this:
db.save('_design/user', {
views: {
byUsername: {
map: 'function (doc) { if (doc.resource === "my_users") { emit(doc._id) } }'
}
}
});
this.db.view('user/byUsername', { key: 'myuser' }, function (err, doc) {
console.dir(doc); ///this is empty array :|
});
but it doesn;t work correctly how to use it ??

You can emit both the _id and password together.
function(doc) {
var key;
if(doc.resource == "my_users") {
key = [doc._id, doc.password];
emit(key, null);
}
}
To find a username/password match, search for the same key.
var username = 'myuser';
var password = 'secret';
var key = [username, password];
this.db.view('users/byUsernamePassword', {"key":key}, function(err, doc) {
console.log("Result:");
console.dir({"err":err, "doc":doc});
})

Related

Check if the body parameter is not null and update on MongoDB

I'm trying to update a document in MongoDB using NodeJS (NextJS). My current code is:
import connect from "../../util/mongodb";
async function api(req, res) {
if (req.method === "POST") {
const { id } = req.body;
const { name } = req.body;
const { email} = req.body;
const { anything1 } = req.body;
const { anything2 } = req.body;
if (!id) {
res.status(400).json({ "error": "missing id param" });
return;
}
const { db } = await connect();
const update = await db.collection("records_collection").findOneAndUpdate(
{ id },
{
$set: {
name,
email,
anything1,
anything2
}
},
{ returnOriginal: false }
);
res.status(200).json(update);
} else {
res.status(400).json({ "error": "wrong request method" });
}
}
export default api;
Everything is working. But I would like to request only the ID as mandatory, and for the other information, leave optional.
In this code, passing the id and name for example, the other three fields (email, anything1 and anything2) will be null in the document.
It is possible to implement the update without requiring all document information and ignore when body fields are null? (As a beginner in NodeJS and MongoDB, the only way to do that that comes to my head now is to surround it all by a lot of if...)
If I've understood your question correctly you can achieve your requirement using the body object in $set stage.
If there is a field which not exists in the object, mongo will not update that field.
As an example check this example where only name field is updated and the rest of fields are not set null.
Another example with 2 fields updated and 3 fields.
You can see how only is updated the field into object in the $set.
So you only need to pass the object received into the query. Something like this:
const update = await db.collection("records_collection").findOneAndUpdate(
{ id },
{
$set: req.body
},
{ returnOriginal: false }
);

How to overwrite an item with a different schema but same key in DynamoDB using nodejs on lambda

I am trying to overwrite an item in DynamoDB (that uses a primary key called username) by using put as shown below:
console.log('writing commands',existingCommands,message.username);
var t2 = performance();
var writeParams = {
Item: {
username: message.username,
commands: existingCommands // Sorry for the confusing name, due to deepExtend existingCommands are the new commands
},
TableName: TableName
};
docClient.put(writeParams, function(err, data){
if(err){
console.error('error',err);
} else {
console.log('write result',data);
var t3 = performance();
console.info('delete & write performance',(t3-t2).toFixed(3));
}
// End function
context.done();
});
That works for:
Inserting a new item where the username doesn't exist.
Updating an item that matches the schema of the Item i'm trying to insert, for example, I'm trying to insert that item:
{
"username":"ausin441062133",
"commands": {
"command1":"command",
"command2":"command"
}
}
and if there's an item that matches the schema and the username it'll get overwritten, i.e.
{
"username":"ausin441062133",
"commands": {
"command1":"I will be overwritten",
"command2":"I will be overwritten"
}
}
But when there's an item with the exact username but different schema, it doesn't work, i.e.
{
"username":"ausin441062133",
"commands": {
"command1":"I will NOT be overwritten"
}
}
What command do I need to use to overwrite an existing item if it matches the username?
Eventually as Dmitry suggested update works but it needs some different params as opposed to put here's my code:
// Step 3 write command back
console.log('writing commands',existingCommands,message.username);
var t2 = performance();
var updateParams = {
Key: {
username: message.username
},
UpdateExpression: "set commands = :c",
ExpressionAttributeValues: {
":c":existingCommands
},
ReturnValues: "UPDATED_NEW",
TableName: TableName
};
docClient.update(updateParams, function(err, data){
if(err){
console.error('error',err);
} else {
console.log('write result',data);
var t3 = performance();
console.info('delete & write performance',(t3-t2).toFixed(3));
}
// End function
context.done();
});

How to access mongoose data : Nodejs

I am getting data like this:
This is the code :
User.find({ Username: user }, function(err, found_user) {
console.log('user data'+ found_user );
if(found_user.length > 0){
console.log('inside found user');
var recordings = found_user.recordings;
console.log(recordings)
for (var singleRecords in recordings){
console.log("Single record :"+singleRecords);
if(!singleRecords.isPlayed){
console.log(singleRecords.playingUrl);
twiml.play(singleRecords.playingUrl);
found_user.recordings[singleRecords].isPlayed = true;
found_user.save(function (err) {
if(err)
throw err
});
}
}
}
And this is the value of found User :
user data { Username: 'B',
__v: 2,
_id: 58ac15e4b4e1232f6f118ba3,
recordings:
[ { isPlayed: false,
playingUrl: 'http://localhost:8000/public/toplay/playing_file_1487672817599.mp3' },
{ isPlayed: false,
playingUrl: 'http://localhost:8000/public/toplay/playing_file_1487672827411.mp3' } ]
}
inside found user
in variable found_user. But it is not giving me any data inside it. Like found_user.Username gives undefined value.
I want to store that recordings array inside a variable. Any idea how to do it ?
find() returns an array of docs that match the criteria in the callback hence the line
var recordings = found_user.recordings;
will not work as it's expecting a Document not an array.
You could use findOne() method which returns a document as:
User.findOne({ Username: user }.exec(function(err, found_user) {
console.log('user data'+ found_user );
if (found_user) {
console.log('inside found user');
var recordings = found_user.recordings;
console.log(recordings);
}
});

check an item collection value mongodb

I would like to know what can I do to check an intem of a collection in mongodb.
the function that I describe below insert users in the db and I would check before the insert if the username exists.
exports.adduser = function(db) {
return function(req, res) {
var userName = req.body.username;
var userEmail = req.body.useremail;
var userCod = req.body.usercod;
var collection = db.get('usercollection');
collection.insert({
'username' : userName,
'email' : userEmail,
'cod' : userCod
}, function (err, doc) {
if (err) {
res.send('There was a problem adding the information to the database.');
}
else {
res.location('userlist');
res.redirect('userlist');
}
});
}
}
var collection = db.get('usercollection');
collection.count({username:username}, function(err, count){
if(err){
return callback(err);
}
if(count > 0){
return callback('User already exists!');
}
//do your insert operation
});
I don't know diddly squat about node.js, but lookups in MongoDB are on the Collection object as find() and findOne(). Assuming your username is enough to make a record unique, the "check if exists" would look like
if ( collection.findOne( { "username" : userName } ) != null ) {
println("username " + userName + " exists!" );
}
The obvious approach would be to add a unique index on username, which will ensure you can't insert duplicates.
The error handling logic will be similar to what you've sketched out in the question description. If a username already existed, there would be an exception when trying to insert and the err string would be something like "E11000 duplicate key error... " (including the offending duplicate key).

How to use a variable as a field name in mongodb-native findOne()?

I have this data in mongodb:
{
"name": "Amey",
"country": "India",
"region": "Dhule,Maharashtra"
}
and I want to retrieve the data while passing a field name as a variable in query.
Following does not work:
var name = req.params.name;
var value = req.params.value;
collection.findOne({name: value}, function(err, item) {
res.send(item);
});
How can I query mongodb keeping both field name and its value dynamic?
You need to set the key of the query object dynamically:
var name = req.params.name;
var value = req.params.value;
var query = {};
query[name] = value;
collection.findOne(query, function (err, item) { ... });
When you do {name: value}, the key is the string 'name' and not the value of the variable name.
Just put the variable in []
var name=req.params.name;
var value = req.params.value;
collection.findOne({[name]:value}, function(err, item) {
res.send(item);
});
I'd like to clarify that if you're trying to make a query concerning a nested field only (not its value), like if you want to query the field "name" from this document:
{
loc: [0, 3],
unit: {
name : "playername"
}
}
this will work (as in my case - using update):
mdb.cords.updateOne(
{_id: ObjectID(someid)},
{$set: {[query]: newValue}},
function (err, result) {
...
}
}
Simply enclosing [query] in brackets tells mongodb that it's not literal, but rather a path.
use like this if the object is nested.
Direct Object:-
var name=req.params.name;
var value = req.params.value;
collection.findOne({[name]:value}, function(err, item) {
res.send(item);
});
An object is nested:-
var surname=req.params.surname;
var value = req.params.value;
var condition = `name.${surname}`
collection.findOne({[condition]:value}, function(err, item) {
res.send(item);
});

Resources