Store timestamp each users in sorted set Redis - node.js

I have a little code:
Add ID:
redis.zadd('onlineusers', time, id, function (err, response) {
//TODO
});
Is a correct way to save current timestamp user with him ID?
Delete ID by KEY:
db.zrem('onlineusers', data.id);
Also, how to get multiple values from sorted set by keys: 1,2,3

Is a correct way to save current timestamp user with him ID?
Yes
You can get the scores of multiple values using multi.
function getScores(setKey, values, callback) {
var multi = db.multi();
for(var i=0; i<values.length; ++i) {
multi.zscore(setKey, values[i]);
}
multi.exec(callback);
}
Usage
getScores('onlineusers', [1,2,3], function(err, scores) {
console.log(err, scores);
});

Related

Loopback Find then update attribute or delete by id

Been trying to find samples usage for some of the static methods for a persistedModel in Loopback.
https://apidocs.strongloop.com/loopback/#persistedmodel-prototype-updateattribute
it just says:
persistedModel.updateAttributes(data, callback)
But how you I choose the which record I want to update? this is not working for me.
var order = Order.setId('whateverrecordId');
order.updateAttributes({name:'new name'},callback)
Loving loopback.. but their doc, sucks.. :(
You can use those on event listener like AfterSave
example:
Model.observe('after save', function(ctx, next) {
ctx.instance.updateAttribute(fieldname:'new value');
next();
});
1- What you did was right but i do not advise this method it's used for instance methods and generally to update fields like date for all the collection that you have so you don't need an id for it.
But you can try to make an array containing data to update containing also the ids and then make a comparison to fill in data for the ids that you have. (in #dosomething)
order.find().then(function(orders) {
orders.forEach(function(element) {
order.setId(element.id);
#DoSomething
order.updateAttribute({new: data}, function(err, instance) {
console.log(instance);
})
});
})
2- You can use updateAll to update one or many attribute.
PersistedModel.updateAll([where], data, callback)
var Updates = [{id : 1, name: name1}, ...]
Updates.forEach(function(element) {
order.updateAll({id : element.id}, {name :element.name}, function(err, count) {
if (err) {
console.error(err);
}
console.log(count); // number of data updated
})
})

NodeJS: Insert record in dynamodb if not exist

I need to store user's info in DynamoDB and send a mail to the same user if it doesn't already exist in DynamoDB table. I am doing this in for loop. The list contains only 2 records. The issue is only the second record gets inserted in table and the mail is sent twice to the same user. Here is the code:
module.exports.AddUser = function(req, res, usersList, departmentId) {
var _emailId = "";
var _userName = "";
var _departmentId = departmentId;
for (var i = 0; i < usersList.length; i++) {
_emailId = usersList[i].emailId;
_userName = usersList[i].userName;
var params = {
TableName: "UsersTable",
Key: {
"emailId": _emailId,
"departmentId": _departmentId
}
};
docClient.get(params, function(err, data) {
if (!err) {
if (!data.items)
AddUserAndSendEmail("UsersTable", _emailId, _userName);
//The above function is being called twice but for the same user.
//It has a check so not inserting the same record twice but
//sending two mails to the same user.
}
});
}
res.end("success");
}
function AddUserAndSendEmail(tableName, emailId, _userName) {
var params = {
TableName: tableName,
Item: {
"emailId": emailId,
"departmentId": 101//Default Department
}
};
docClient.put(params, function(err, data) {
if (!err) {
//Send Email Code Here
} else {
console.log("error");
}
});
}
What could be the reason for this strange behavior? Really frustrated, I am about to give up on this.
1) Please note that DynamoDB is eventually consistent. If you insert the item and check whether the item exists immediately, it may not always find the item in the database.
This means the second iteration of the loop may not always find the first item inserted into the table.
2) If the item already exists in the table, the Put api will update the item and give successful response.
This means the Put will be successful for the same email id and department id in the second iteration because it updates the record if it is already present.
GetItem – The GetItem operation returns a set of Attributes for an
item that matches the primary key. The GetItem operation provides an
eventually consistent read by default. If eventually consistent reads
are not acceptable for your application, use ConsistentRead.
PutItem – Creates a new item, or replaces an old item with a new item
(including all the attributes). If an item already exists in the
specified table with the same primary key, the new item completely
replaces the existing item. You can also use conditional operators to
replace an item only if its attribute values match certain conditions,
or to insert a new item only if that item doesn’t already exist.
Based on the above points, there is a possibility to get two emails if you have same email id and department id in the array.

Mongoose count skip limit

I am implementing pagination.
What I am doing is counting the items from collection first & after that count will return. I am then doing another find with skip and limit.
Now I want to assign count to the data returned by 2nd query which I am not able to do.
I tried toObject() but I am getting error "toObject() is not a function".
I don't want to use any library.
ErrorReportModel.find().count(function(err, count) {
if (err) {
console.log(err);
utile.internalError(res);
}
ErrorReportModel.find().sort({
date_create: -1
}).limit(20).skip(query.page * 20).lean().exec(function(err, data) {
if (err) {
console.log(err);
utile.internalError(res);
}
// i am doing this at the moment
var myData = {};
myData.data=data;
myData.count = count;
utile.response(res, myData);
});
});
I want to send the count to client side because I want to display page_number buttons depending on that count.

how to improve the view with map/reduce in couchdb and nodejs

I'm using nodejs with the module cradle to interact with the couchdb server, the question is to let me understanding the reduce process to improve the view query...
For example, I should get the user data from his ID with a view like this:
map: function (doc) { emit(null, doc); }
And in node.js (with cradle):
db.view('users/getUserByID', function (err, resp) {
var found = false;
resp.forEach(function (key, row, id) {
if (id == userID) {
found = true;
userData = row;
}
});
if (found) {
//good, works
}
});
As you can see, this is really bad for large amount of documents (users in the database), so I need to improve this view with a reduce but I don't know how because I don't understand of reduce works.. thank you
First of all, you're doing views wrong. View are indexes at first place and you shouldn't use them for full-scan operations - that's ineffective and wrong. Use power of Btree index with key, startkey and endkey query parameters and emit field you like to search for as key value.
In second, your example could be easily transformed to:
db.get(userID, function(err, body) {
if (!err) {
// found!
}
});
Since in your loop you're checking row's document id with your userID value. There is no need for that loop - you may request document by his ID directly.
In third, if your userID value isn't matches document's ID, your view should be:
function (doc) { emit(doc.userID, null); }
and your code will be looks like:
db.view('users/getUserByID', {key: userID}, function (err, resp) {
if (!err) {
// found!
}
});
Simple. Effective. Fast. If you need matched doc, use include_docs: true query parameter to fetch it.

How to query data from different collections and sort by date?

I stumbled upon problem that my search results are of a mixed data, which is located in different collections (posts/venues/etc), currently Im doing separate requests to retrieve this data, but its obviously sorted among its types (posts array, venues array)
How can I query multiple collections (posts/venues) and sort them by date/any other parameter (via mongoose)?
or maybe there is a better solution?
Thanks
I believe its not possible with Mongoose, you can in the meanwhile do something like this:
var async = require('async');
function getPosts(cb) {
Post.find({"foo": "bar"}, function(err, posts) {
cb(err, posts);
})
}
function getVenues(cb) {
Venue.find({"foo": "bar"}, function(err, venues) {
cb(err, venues);
})
}
async.parallel([getPosts, getVenues], function(err, results) {
if(err) {
next(err);
}
res.send(results.sort(function(a, b) {
//if default sorting is not enough you can change it here
return a.date < b.date ? -1 : a.date > b.date ? 1 : 0;
}));
});
This code assumes you are inside an express route and that both Posts and Venues have a common attribute; date. In case you named these dates attributes differently you would have to improve the sort algorithm.

Resources