I have a node.js app that connects and saves to a mongodb collection.
var durations = []
for (i = 0; i < 5; i++) {
var start = performance.now();
//do stuff
var end = performance.now();
durations.push(end - start);
}
var sum, avg = 0;
if (durations.length)
{
sum = durations.reduce(function(a, b) { return a + b; });
avg = sum / durations.length;
}
objectToSave.durationAverage = avg;
console.log(durations);
console.log(avg);
//Add the object to the database through Ajax
$.ajax({
type:'POST',
url:'/add',
data:JSON.stringify(objectToSave),
contentType: "application/json; charset=utf-8",
dataType: "json"
});
On the console :
console.log(durations);
[0.10000000111176632, 0, 0, 0, 0]
console.log(avg);
0.020000000222353265
In my collection:
{ durationAverage : 0 }
How can i save the value with 4 digits after the decimal from node.js to mongodb?
Thank you
Related
The code below only output the last result, I don't get it. I check if the updateDate item contains 2020-05 both items does and I get only the last one. The loop is not looping :)
const briefing = [
{
"updateDate": "2020-05-05T00:00:00.0Z",
},
{
"updateDate": "2020-05-06T00:00:00.0Z",
},
{
"updateDate": "2020-05-13T00:00:00.0Z",
}
];
let date = new Date();
var formattedYearMonth = date.getFullYear() + '-' + ('0' + (date.getMonth()+1)).slice(-2) + '-';
for (var i = 0; i < briefing.length; i++) {
var jsonDate = briefing[i].updateDate;
if (jsonDate.includes(formattedYearMonth)) {
var response = JSON.stringify(briefing[i]);
}
}return response;
}
for (var i = 0; i < briefing.length; i++) {
var jsonDate = briefing[i].updateDate;
if (jsonDate.includes(formattedYearMonth)) {
var response = JSON.stringify(briefing[i]); // <==== THIS IS WHERE YOUR PROBLEM LIES
}
}return response;
The loop is actually looping :). But for every run of the loop, you are resetting the value of response.
--EDITED--
For the response to be an array, you need to modify your code as
let response = [];
for (var i = 0; i < briefing.length; i++) {
var jsonDate = briefing[i].updateDate;
if (jsonDate.includes(formattedYearMonth)) {
response.push(JSON.stringify(briefing[i]));
}
}
return response;
So i ran into a problem. I don't know how to pass single string to the parental function from a child function and then pass that string as a response to the client side.
This whole thing gets five recent matches from API and then checks for a win or a loss depending on the player name.
Question 1: as i said before i don't know how to pass string from a child function to the parental function and then send it as a response to client side.
Question 2: the output of this should be WWWLW and how i think it should be ordered like that. But every time it outputs in different order like LWWWW WLWWW and so on... it has good arguments but different order and i am missing something here.
code:
var request = require('request');
app.get('/history',getmatches, getwins);
function getmatches(req, res, next){
var match = {};
request({
url: "https://eun1.api.riotgames.com/lol/match/v3/matchlists/by-account/"+ID+"/recent?api_key=" + key,
json: true
}, function (error, res) {
if (!error && res.statusCode === 200) {
for(var i=0; i < 5; i++){ //getting ID's of five last matches
match[i] = res.body.matches[i].gameId;
}
req.somevariable = match;
next();
}
}
);
};
function getwins(req, res, callback){
var match = req.somevariable;
var streak = '';
var pending = 0;
for( i = 0; i < 5; i++){ // passing ID's to another api link to get single match data
request({
url: "https://eun1.api.riotgames.com/lol/match/v3/matches/"+match[i]+"?api_key=" + key,
json: true
}, function(req,res, body){
for(var j = 0; j < 10; j++){ //looping through 10 players in a match to find specific one
if(body.participantIdentities[j].player.summonerName == nickname){
if( body.participants[j].stats.win == true){
streak += 'W';
}else{
streak += 'L';
}
}
}
if(pending == 4){
console.log(streak); // need this to pass to parent function
return callback(null, streak); // is this something i need ?
}
pending++
});
}
// res streak string to client.js
};
There is solution to process all results when it done. The result variable have all results use any appropriate key instead of url;
function getwins(req, res, callback){
var match = req.somevariable;
var streak = '';
var pending = 0;
var results = {};
var total = 5;
for( i = 0; i < total; i++){ // passing ID's to another api link to get single match data
var url = "https://eun1.api.riotgames.com/lol/match/v3/matches/"+match[i]+"?api_key=" + key;
request({
url: url,
json: true
}, function(req,res, body){
for(var j = 0; j < 10; j++){ //looping through 10 players in a match to find specific one
if(body.participantIdentities[j].player.summonerName == nickname){
if( body.participants[j].stats.win == true){
streak += 'W';
}else{
streak += 'L';
}
}
}
console.log(streak); // need this to pass to parent function
results[url] = streak;
if( total == Object.keys(results).length ) {
// here all requests are done - do with all result what you need
console.log( results );
}
return callback(null, streak); // is this something i need ?
}
});
}
// res streak string to client.js
};
The terminal out is:
but actually this is what I really want:
progressbar will alway be the fist line,and got a response,then show it at below.
anyway to fix that?
Nodejs:
var request = require('request');
var ProgressBar = require('progress');
var year=[14,15,16];
var month=[1,2,3,4,5,6,7];
var bar = new ProgressBar('Processing [:bar] :percent', {
complete: '=',
incomplete: '-',
width: 30,
total: year.length*month.length,
});
/*-------------------------------------*/
function init(year,month){
check(year,month);
}
function check(year,month){
var options = { method: 'POST',
url: 'http://dev.site/date.php',
formData:{year:year,month:month}
};
request(options, function (error, response, body) {
if (error) {
console.log(error);;
}
if (body=='A task #') {
bar.tick();
console.log('\n'+body+year+':'+month);
}else{
bar.tick();
}
})
}
/*-------------------------------------*/
for (var i = 0; i < year.length; i++) {
for (var n = 0; n < month.length; n++) {
init(year[i],month[n]);
}
}
Using ansi-escapes you may be able to do this.
Here's a standalone version:
const ProgressBar = require('progress');
const ansiEscapes = require('ansi-escapes');
const write = process.stdout.write.bind(process.stdout);
let bar = new ProgressBar('Processing [:bar] :percent', {
complete : '=',
incomplete : '-',
width : 30,
total : 100
});
// Start by clearing the screen and positioning the cursor on the second line
// (because the progress bar will be positioned on the first line)
write(ansiEscapes.clearScreen + ansiEscapes.cursorTo(0, 1));
let i = 0;
setInterval(() => {
// Save cursor position and move it to the top left corner.
write(ansiEscapes.cursorSavePosition + ansiEscapes.cursorTo(0, 0));
// Update the progress bar.
bar.tick();
// Restore the cursor position.
write(ansiEscapes.cursorRestorePosition);
// Write a message every 10 ticks.
if (++i % 10 === 0) {
console.log('Now at', i);
}
// We're done.
if (i === 100) {
process.exit(0);
}
}, 100);
I'm trying to alter the interval by using a the variable 'counter'.
The Twitter stream is working and the LED is blinking.
I have removed all the twitter credentials.
Any help would be greatly appreciated!
Here is my code:
var Gpio = require('onoff').Gpio;
var Twit = require('twit');
var T = new Twit({
consumer_key: '' // Your Consumer Key
, consumer_secret: '' // Your Co$
, access_token: '' // Your Ac$
, access_token_secret: '' // Your Access $
});
var stream = T.stream('statuses/filter', { track: '#blessed, #peace'})
led = new Gpio(17, 'out'),
counter = 500;
stream.start();
var iv = setInterval(function(){
led.writeSync(led.readSync() === 0 ? 1 : 0);
}, counter);
stream.on('tweet', function(tweet) {
if(tweet.text.indexOf('#blessed') > -1) {
console.log("blessed");
counter += 100;
} else if (tweet.text.indexOf('#peace') > -1) {
console.log("peace");
counter -= 100;
}
});
Once you've made the setInterval() call, the timer's locked in, you can't change it. This is how arguments to functions work: Changing them after the fact does nothing. There is no binding to the value supplied, numbers get passed in as a copy.
You'll need to clear and re-set the timer. setInterval() returns a handle you can pass through to clearInterval() to turn it off. You've captured this, so you just need to use it:
var iv;
function blink(interval) {
if (iv) {
clearInterval(iv);
}
iv = setInterval(function() {
led.writeSync(led.readSync() === 0 ? 1 : 0);
}, interval);
}
Then use this function to reset it:
counter -= 100;
blink(counter);
Just make sure you don't go negative.
I added a check to counter and interval:
var Gpio = require('onoff').Gpio;
var Twit = require('twit');
var T = new Twit({
consumer_key: '' // Your Consumer Key
, consumer_secret: '' // Your Co$
, access_token: '' // Your Ac$
, access_token_secret: '' // Your Access $
});
var stream = T.stream('statuses/filter', { track: '#blessed, #peace'})
led = new Gpio(17, 'out'),
counter = 200;
stream.start();
var iv;
function blink(interval) {
if (iv) {
clearInterval(iv);
}
if (interval <= 100) {
interval = 100;
}
console.log("interval = " + interval);
iv = setInterval(function(){
led.writeSync(led.readSync() === 0 ? 1 : 0);
}, interval);
}
stream.on('tweet', function(tweet) {
if(tweet.text.indexOf('#blessed') > -1) {
console.log("blessed");
counter += 100;
if (counter <= 100) {
counter = 100;
}
console.log(counter);
blink(counter);
} else if (tweet.text.indexOf('#peace') > -1) {
console.log("peace");
counter -= 100;
if (counter <= 100) {
counter = 100;
}
console.log(counter);
blink(counter);
}
});
I have a Node.js application that saves data to MongoDB.
Given one document, I want to find the most similar document in the database.
My idea is to implement some sort of nearest neighbour algorithm that takes all the records as a training sequence and returns the most similar document (including some sort of percentage on how similar these two documents are.)
E.g. having these records in my database...
{ name: "Bill", age: 10, pc: "Mac", ip: "68.23.13.8" }
{ name: "Alice", age: 22, pc: "Windows", ip: "193.186.11.3" }
{ name: "Bob", age: 12, pc: "Windows", ip: "56.89.22.1" }
...I want to find the closest document to this one
{ name: "Tom", age: 10, pc: "Mac", ip: "68.23.13.10" }
// algorithm returns "Bill", .76
Are there any Node modules/implementations that take any kind of objects/parameters and return their nearest neighbour?
Here is some example code. It assumes that you can run the search on every request. If you want to modify it, make sure that all similarity functions return a number between 0 and 1.
function tokenize(string) {
var tokens = [];
for (var i = 0; i < string.length-1; i++) {
tokens.push(string.substr(i,2));
}
return tokens.sort();
}
function intersect(a, b)
{
var ai=0, bi=0;
var result = new Array();
while( ai < a.length && bi < b.length )
{
if (a[ai] < b[bi] ){ ai++; }
else if (a[ai] > b[bi] ){ bi++; }
else /* they're equal */
{
result.push(a[ai]);
ai++;
bi++;
}
}
return result;
}
function sum(items) {
var sum = 0;
for (var i = 0; i < items.length; i++) {
sum += items[i];
}
return sum;
}
function wordSimilarity(a, b) {
var left = tokenize(a);
var right = tokenize(b);
var middle = intersect(left, right);
return (2*middle.length) / (left.length + right.length);
}
function ipSimilarity(a, b) {
var left = a.split('.');
var right = b.split('.');
var diffs = [];
for (var i = 0; i < 4; i++) {
var diff1 = 255-left[i];
var diff2 = 255-right[i];
var diff = Math.abs(diff2-diff1);
diffs[i] = diff;
}
var distance = sum(diffs)/(255*4);
return 1 - distance;
}
function ageSimilarity(a, b) {
var maxAge = 100;
var diff1 = maxAge-a;
var diff2 = maxAge-b;
var diff = Math.abs(diff2-diff1);
var distance = diff / maxAge;
return 1-distance;
}
function recordSimilarity(a, b) {
var fields = [
{name:'name', measure:wordSimilarity},
{name:'age', measure:ageSimilarity},
{name:'pc', measure:wordSimilarity},
{name:'ip', measure:ipSimilarity}
];
var sum = 0;
for (var i = 0; i < fields.length; i++) {
var field = fields[i];
var name = field.name;
var measure = field.measure;
var sim = measure(a[name], b[name]);
sum += sim;
}
return sum / fields.length;
}
function findMostSimilar(items, query) {
var maxSim = 0;
var result = null;
for (var i = 0; i < items.length; i++) {
var item = items[i];
var sim = recordSimilarity(item, query);
if (sim > maxSim) {
maxSim = sim;
result = item;
}
}
return result
}
var items = [
{ name: "Bill", age: 10, pc: "Mac", ip: "68.23.13.8" },
{ name: "Alice", age: 22, pc: "Windows", ip: "193.186.11.3" },
{ name: "Bob", age: 12, pc: "Windows", ip: "56.89.22.1" }
];
var query = { name: "Tom", age: 10, pc: "Mac", ip: "68.23.13.10" };
var result = findMostSimilar(items, query);
console.log(result);
A straightforward way of doing this would be to calculate a diff between the two documents and the larger the diff, the larger the distance. You could normalize the diff using the maximum possible diff which should give you relative distances that you can compare against each other.
Take a look at this question for calculating a diff on json documents.
Delta encoding for JSON objects