Mongojs find by uuid _id - node.js

I am trying to find one record with "monogjs" by _id.
Our _id is a guid (.net).
So I have something like this "80cd95b8-79bf-4025-933b-cabc71fbdc9f" as a string.
Now I tried "monogdb.bsonpure" with a "buffer" specifying the subtype of uuid.
I tried passing it to objectid() but then it tells me it need to be a hex string 12/24.
I just passed it as string but then it just does not return anything

Ok this works
Take "80cd95b8-79bf-4025-933b-cabc71fbdc9f" remove "-"
var Binary = require('mongodb').Binary;
var uuid = require('node-uuid');
var base64data = new Buffer(uuid.parse(param), 'binary').toString('base64');
var bin = new Buffer(base64data, 'base64');
var id = new Binary(bin, Binary.SUBTYPE_UUID_OLD);

So the accepted answer didn't work for me. I found a snippet of code in this github issue to parse a .net guid into a buffer:
guid-parse.js:
'use strict';
// Maps for number <-> hex string conversion
var _byteToHex = [];
var _hexToByte = {};
for (var i = 0; i < 256; i++) {
_byteToHex[i] = (i + 0x100).toString(16).substr(1);
_hexToByte[_byteToHex[i]] = i;
}
// **`parse()` - Parse a UUID into it's component bytes**
function parse(s, buf, offset) {
const i = (buf && offset) || 0;
offset = i;
let ii = 0;
buf = buf || Buffer.alloc(16 + i);
s.toLowerCase().replace(/[0-9a-f]{2}/g, function(oct) {
if (ii < 16) { // Don't overflow!
buf[i + ii++] = _hexToByte[oct];
}
});
// Zero out remaining bytes if string was short
while (ii < 16) {
buf[i + ii++] = 0;
}
// Endian-swap hack...
var buf2 = Buffer.from(buf);
buf[offset+0] = buf2[offset+3];
buf[offset+1] = buf2[offset+2];
buf[offset+2] = buf2[offset+1];
buf[offset+3] = buf2[offset+0];
buf[offset+4] = buf2[offset+5];
buf[offset+5] = buf2[offset+4];
buf[offset+6] = buf2[offset+7];
buf[offset+7] = buf2[offset+6];
return buf;
}
// **`unparse()` - Convert UUID byte array (ala parse()) into a string**
function unparse(buf, offset) {
let i = offset || 0;
// Endian-swap hack...
var buf2 = Buffer.from(buf);
buf[i+0] = buf2[i+3];
buf[i+1] = buf2[i+2];
buf[i+2] = buf2[i+1];
buf[i+3] = buf2[i+0];
buf[i+4] = buf2[i+5];
buf[i+5] = buf2[i+4];
buf[i+6] = buf2[i+7];
buf[i+7] = buf2[i+6];
const bth = _byteToHex;
return bth[buf[i++]] + bth[buf[i++]] +
bth[buf[i++]] + bth[buf[i++]] + '-' +
bth[buf[i++]] + bth[buf[i++]] + '-' +
bth[buf[i++]] + bth[buf[i++]] + '-' +
bth[buf[i++]] + bth[buf[i++]] + '-' +
bth[buf[i++]] + bth[buf[i++]] +
bth[buf[i++]] + bth[buf[i++]] +
bth[buf[i++]] + bth[buf[i++]];
}
module.exports = {
parse,
unparse
};
Then I used it like this:
const mc = require('mongodb').MongoClient;
const { Binary } = require('mongodb').Binary
const guidParse = require("./guid-parse.js");
const NUUID = guidString => {
return new Binary(guidParse.parse(guidString), Binary.SUBTYPE_UUID_OLD);
};
mc.connect('mongodb://localhost:27017/database').then( conn => {
const db = conn.db('database');
return db
.collection('users')
.find({
Guid: NUUID("9EC5955B-E443-456A-A520-8A87DED37EBB")
})
.toArray();
}).then( users => {
console.log(users);
});
And it returned the collection I was looking for!

Related

firebase cloud function ServerValue increment not working

i have a firebase function. I want to make increment ServerValue here. but it doesn't work it gives an error. where did i go wrong?
I am attaching the console screenshot below. (note : I don't know javascript very well, there may be errors in java codes as well.)
const functions = require("firebase-functions");
const admin = require("firebase-admin");
admin.initializeApp(functions.config().firebase);
const database = admin.database();
async function sirala(dil, lig, oyunTipi) {
await database.ref("/turnuvalar/" + dil + "/" + lig + "/" + oyunTipi + "/users/").once("value").then(async function(snap) {
const users = [];
const updatesLig = {};
const refLig = database.ref().child("ligler").child(dil).child(lig).child("users");
snap.forEach((childSnap) => {
const id = childSnap.key;
const puan = childSnap.child("puan").val();
const serverTime = childSnap.child("serverTime").val();
users.push(new Person(id, puan, serverTime));
});
users.sort((a, b) => parseFloat(a.serverTime) - parseFloat(b.serverTime));
for (let i = 0; i < users.length; i++) {
let group = [];
const grupSayi = 3;
if (i < grupSayi) {
group = users.slice(0, grupSayi);
} else {
group = users.slice(i + 1 - grupSayi, i + 1);
}
group.sort((a, b) => parseFloat(b.puan) - parseFloat(a.puan));
const index = (element) => element.id === users[i].id;
const sira = (group.findIndex(index) + 1);
// const increment = database.ServerValue.increment(kupaAdet(sira));
const kupa = {
puan: database.ServerValue.increment(1), /// ??? ERROR IS THERE ???
};
updatesLig[users[i].id + "/"] = kupa;
console.log("user id " + users[i].id + " kupa - " + kupaAdet(sira) + " sira - " + sira);
for (let g = 0; g < group.length; g++) {
console.log("grup : " + (i + 1) + " - " + group[g].id + " - " + group[g].puan + " - " + group[g].serverTime);
}
}
await refLig.update(updatesLig);
return null;
}).catch((error) => {
console.log(error);
});
}
error screenshot :
It looks like your database is an instance of firebase.database() (note the parentheses in there). The ServerValue property is defined on firebase.database without parentheses, so that explains why the increment cannot be found.
You'll want to use either admin.database.ServerValue.increment(1) or firebase.database.ServerValue.increment(1), depending on how you import the Admin SDK.

how to read json file and search with filter for common items in nodejs

I have JSON file contain games objects, I want to get top 5 games that have the highest total playtime between users.
I tried to get all objects by reading the file using file system in nodejs :
const queryGames = async () => {
let data = fs.readFileSync(path.resolve(__dirname, '../../games.json'))
let games = JSON.parse(data)
return games
}
/**
* Query for top games by play time
* #returns {Promise<QueryResult>}
*/
const selectTopByPlaytime = async () => {
}
this is the json file : https://jsoneditoronline.org/#left=cloud.3b82169327044c04b7207fa186aee85b&right=local.tiniqu
something like this should work.
const gamePlayData = require('./gamePlay.json').data
/**
* Query for games and time
* #returns {
'League of legends': 1650,
'World of warcraft': 2300,
'Dark Souls': 218,
'The Witcher 3: Wild Hunt': 987,
etc....
}
*/
const getGamePlayTimes = () => {
gamePlayTimes = {}
gamePlayData.forEach( (playData) => {
const gameName = playData.game
if(gamePlayTimes[gameName]) {
gamePlayTimes[gameName] += playData.playTime
}
else {
gamePlayTimes[gameName] = playData.playTime
}
})
return gamePlayTimes;
}
const getGamesAndTimesAsList = (playTimes) => {
let gamesWithTimeArr = [];
let i = 0;
for(let game in playTimes) {
let gameAndPlayTime = {game: "", playTime: 0};
gameAndPlayTime.game = game;
gameAndPlayTime.playTime = playTimes[game];
gamesWithTimeArr[i++] = gameAndPlayTime
}
return gamesWithTimeArr;
}
const reverseBubbleSort = (a, par) => {
let swapped;
do {
swapped = false;
for (var i = 0; i < a.length - 1; i++) {
if (a[i][par] < a[i + 1][par]) {
var temp = a[i];
a[i] = a[i + 1];
a[i + 1] = temp;
swapped = true;
}
}
} while (swapped);
return a;
}
sortedArr = reverseBubbleSort(getGamesAndTimesAsList( getGameAndPlayTimes() ) , 'playTime')
const top5 = sortedArr.slice(0, 5);
console.log(top5);

Edit a JSON object

I retrieved a JSON object from a local database, I want to edit a value (invItems) and add a new value to it (filed[filed.invItems]), then upload it back to the database, but it does not seem to work (the JSON does not seem to change)
async function invPut(itemID, message) {
var filed = await frenzyDB.getKey(id + "_invcache");
console.log("Before: " + filed)
newInvItems = filed.invItems + 1;
filed.invItems = newInvItems;
filed[filed.invItems] = itemID;
console.log("After: " + filed);
await frenzyDB.addKey(id + "_invcache", filed)
}
Console Output:
Before: {"invItems":0}
After: {"invItems":0}
It shows no errors, but the JSON doesnt change. Am I doing something wrong? If so, what can I do to fix it?
Thanks for all your help!
Notes:
frenzyDB is just a javascript file that deals with a standard REPL.it Database
Code of frenzyDB:
const Database = require("#replit/database")
const db = new Database()
async function addKey(key, value) {
await db.set(key, value).then(() => {return;});
}
async function getKey(key) {
return await db.get(key).then(value => {return value;});
}
function listAllKeys() {
db.list().then(keys => {return keys;});
}
async function hasKey(key) {
var keys = await listAllKeys();
if (keys.includes(key)) {
return true;
} else {
return false;
}
}
async function removeKey(key) {
await db.delete(key).then(() => {return;});
}
module.exports = {
addKey,
getKey,
listAllKeys,
hasKey,
removeKey
};
Edit: Latest code:
async function invPut(itemID, message) {
await init(message.author.id);
var filed = await frenzyDB.getKey(message.author.id + "_invcache");
console.log(filed)
const result = {};
result.invItems = (filed['invItems'] + 1) || 1;
result.hasOwnProperty(filed.invItems) ? result[filed.invItems + 1] = itemID : result[filed.invItems] = itemID;
console.log(result);
frenzyDB.addKey(message.author.id + "_invcache", result)
message.reply("A **"+ itemIDs[itemID].name + "** was placed in your inventory");
return true;
}
EDIT 2: Latest Console Output:
{ '4': 3, invItems: 5 }
{ '5': 3, invItems: 6 }
Any help will be appreciated!
Thanks
Try this
// Demo Data
const itemID = 10;
var filed = { "invItems" : 0 };
// Real function
console.log("Before: " + JSON.stringify(filed));
const result = {};
result.invItems = (filed['invItems'] + 1) || 1;
result.hasOwnProperty(filed.invItems) ? result[filed.invItems + 1] = itemID : result[filed.invItems] = itemID;
console.log("After: " + JSON.stringify(result));
The result I get is
Before: {"invItems":0}
After: {"0":10,"invItems":1}
You would then of course use result to store the data away in the DB.
async function invPut(itemID, message) {
// Typo?
var filed = await frenzyDB.getKey(itemID + "_invcache");
console.log("Before: " + filed)
const result = {};
result.invItems = (filed['invItems'] + 1) || 1;
result.hasOwnProperty(filed.invItems) ? result[filed.invItems + 1] = itemID : result[filed.invItems] = itemID;
console.log("After: " + result);
// Typo?
await frenzyDB.addKey(itemID + "_invcache", result)
}
Answer Edit:
const result = { ...filed };
result.invItems = (filed['invItems'] + 1) || 1;
result.hasOwnProperty(filed.invItems) ? result[filed.invItems + 1] = itemID : result[filed.invItems] = itemID;
console.log(JSON.stringify(result));
maybe this will help you
const json = fs.readFileSync(`${__dirname}/data/data.json`, "utf-8");
const inputData = JSON.parse(json);
inputData.push({input: 'front'}) // creates new element for data.json
-------------------------------------------
array.push({front: 'front', back: 'back'});

Problem with findOne() in sequelize node.js

I have a problem with node.js and sequelize findOne(). I want to find new students, that I want to add to the DB (var novi), and the ones that already exist, I just want to update their field (var stari). Everything works as expected, only when I want to return JSON with how many new students I added to the DB, and how many are updated, values of stari and novi, go back to 0, but the counting is good, I checked. I know the problem is with asynchronous call, but I don't know how to fix.
app.post('/student', function(req,res) {
var imeGodine = req.body['godina'];
//POMOĆNE SKRIPTE BitBucket.js i citanjeGodina.js
var broj = 0;
var stari = 0;
var novi = 0;
db.godina.findOne({where:{nazivGod:req.body.godina}}).then(god => {
var studenti = req.body.studenti;
db.student.count().then (ranijeStudenata => {
for(var i = 0; i<studenti.length; i++) {
var ime = studenti[i].imePrezime;
var ind = studenti[i].index;
db.student.findOne({where:{index :studenti[i].index}}).then(stud => {
if (stud == null) {
novi++;
db.student.create({imePrezime:ime, index : ind}).then(noviStudent => {
god.addStudenti(noviStudent);
});
}
else if (stud != null) {
stari++;
god.addStudenti(stud);
}
});
broj++;
}
var brojNovih = broj - ranijeStudenata; //ne koristi se, ali možda hoće
res.set("Content-Type", "application/json");
res.status(200).send(JSON.stringify({message: "Dodano je " + novi + " novih studenata i upisano " + stari + " na godinu " + imeGodine}));
});
});
});
Picture of code
You can use async/await to do counting in a synchronous way.
'use strict';
app.post('/student', async function (req, res) {
var imeGodine = req.body['godina'];
var {studenti} = req.body;
var broj = 0;
var stari = 0;
var novi = 0;
let god = await db.godina.findOne({where: {nazivGod: req.body.godina}});
let ranijeStudenata = await db.student.count(); // ranijeStudenata not used?
for (var i = 0; i < studenti.length; i++) {
var ime = studenti[i].imePrezime;
var ind = studenti[i].index;
let stud = await db.student.findOne({where: {index: studenti[i].index}});
if (stud === null) {
novi++;
let noviStudent = await db.student.create({imePrezime: ime, index: ind});
god.addStudenti(noviStudent);
} else if (stud !== null) {
stari++;
god.addStudenti(stud);
}
broj++;
}
return res.status(200).send({
message: "Dodano je " + novi + " novih studenata i upisano " + stari + " na godinu " + imeGodine
});
});

node js function.then in not a function using q

Hello its so wired i am trying to do async function but when i use it i get error
using q
on package json
"q": "^1.4.1"
TypeError: helper.setNextUserNewsAction(...).then is not a function
this is my helper
module.exports = function() {
return {
setNextUserNewsAction: setNextUserNewsAction
}
}();
function setNextUserNewsAction(minutesToSet){
var defer = q.defer();
var x = minutesToSet;
var d = new Date();
var nextNews = new Date(d.getTime() + x*60000);
var minutes = nextNews.getMinutes();
var newMinutesToSet = 0;
for (var i = 0 , j = minutesToSet; j <= 60; i+=minutesToSet,j+=minutesToSet) {
if (minutes > i && minutes < j)
return newMinutesToSet = (i % 60);
}
nextNews.setMinutes(newMinutesToSet);
nextNews.setSeconds(00);
var NextNewsAction = {
AccessDate: nextNews,
Type: 'News',
Current: 1
}
defer.resolve(NextNewsAction);
return defer.promise;
}
and when i call this function in my controller it send me that error
var helper = require('../helpers/playlist');
helper.setNextUserNewsAction(15).then(function(action){
console.log(action);
},function(err){
console.log(err);
});
i have also try doing that with try and catch and still same error
well its not the first time or the 20 i am using q
hope somebody can help
The problem is that you are returning something from the for loop:
for (var i = 0, j = minutesToSet; j <= 60; i += minutesToSet, j += minutesToSet) {
if (minutes > i && minutes < j)
return newMinutesToSet = (i % 60);
}
So the setNextUserNewsAction function is not returning a promise, therefore there is no .then().
Try this:
var q = require('q');
module.exports = function() {
return {
setNextUserNewsAction: setNextUserNewsAction
}
}();
function setNextUserNewsAction(minutesToSet){
var defer = q.defer();
var x = minutesToSet;
var d = new Date();
var nextNews = new Date(d.getTime() + x*60000);
var minutes = nextNews.getMinutes();
var newMinutesToSet = 0;
for (var i = 0, j = minutesToSet; j <= 60; i += minutesToSet, j += minutesToSet) {
if (minutes > i && minutes < j) {
newMinutesToSet = (i % 60);
}
}
nextNews.setMinutes(newMinutesToSet);
nextNews.setSeconds(00);
var NextNewsAction = {
AccessDate: nextNews,
Type: 'News',
Current: 1
}
defer.resolve();
return defer.promise;
}

Resources