const { promisify } = require('util');
const index = require('../../../index');
//get caching data in redis
const redisGet = async(key) => {
const getAsync = promisify(index.clientRedis.get).bind(index.clientRedis);
const value = await getAsync(key);
return value;
}
module.exports = redisGet;
My "redisGet" function return right value at the first time, and later times, it only return "null" although the caching data is still exist.
const cachingData = await redisGet('key');//first time: cachingData = <right value>//later times: cachingData = null
How can I fix it ?
Hope for solutions. Thanks all !
You might be storing the key with a TTL value.
After the TTL is up the key is expired and null is returned if you try to fetch the key.
ref: https://redis.io/commands/expire/
Related
So I'm working on a project where I'm making a call to a database to retrieve the data stored there. This data comes as an array. here is the code:
const allLogins = await Login.find().sort("name");
const token = req.header("x-auth-token");
const user = jwt.verify(token, config.get("jwtPrivateKey"));
const logins = allLogins
.filter((login) => login.userId === user._id)
.map((login) => {
login.password = decrypt(login.password);
});
If I call a console.log after the decrypt has been run I see that it has been completed correctly. The issue I have is if I console.log(logins) it says it is an array of two items that are both undefined. If instead I run it like this...
const allLogins = await Login.find().sort("name");
const token = req.header("x-auth-token");
const user = jwt.verify(token, config.get("jwtPrivateKey"));
let logins = allLogins.filter((login) => login.userId === user._id);
logins.map((login) => {
login.password = decrypt(login.password);
});
Then it works as it should. I'm not sure why the first set of code doesn't work and why the second set does work.
Any help would be appreciated!
Basic :
array. filter - accept a callback and call back return boolean (that match our criteria)
array.map - accept a callback and call back return transformed object
In the second working example:
logins.map((login) => {
// note: logins is iterated but not assigned to logins back
// so accessing login is working
login.password = decrypt(login.password); // map should return data
+ return login; // if we update all code will work
});
Now coming to first example:
const logins = allLogins
.filter((login) => login.userId === user._id)
.map((login) => {
login.password = decrypt(login.password);
+ return login; // this will fix the issue
});
Using the ipfs-http-client I can successfully add data using the below method. The console.log(added) returns an object with the path, cid, and size keys.
However, the console.log(exists) line returns Object [AsyncGenerator] {}.
I would like to be able to check if a data string exists. Is this possible?
import { create as ipfsHttpClient } from 'ipfs-http-client'
const ipfsClient = ipfsHttpClient('https://ipfs.infura.io:5001/api/v0')
const handleData = async (data) => {
const added = await ipfsClient.add(data)
console.log(added)
const exists = await ipfsClient.get(data)
console.log(exists)
}
handleData('hello world')
The get method returns AsyncIterable<Uint8Array> object, which may be what you're printing out. To get each bytes, you will have to loop over it:
const cid = 'QmQ2r6iMNpky5f1m4cnm3Yqw8VSvjuKpTcK1X7dBR1LkJF'
for await (const buf of ipfs.get(cid)) {
// do something with buf
console.log(buf);
}
If all you care about is whether the data exists, you can just call next() method on the iterator and check for null or error.
const exists = (await ipfs.get(cid)).next() !== null
Right now, I coded a function to go like this
async function checkPlayerScam(ign) {
const UUID = await getUUID(ign);
if(MATCHING){
playerIsScammer = true
}
else {
playerIsScammer = false
}
}
The MATCHING is just a placeholder at the moment. I want to check their UUID, and make sure it isn't in this list: https://raw.githubusercontent.com/skyblockz/pricecheckbot/master/scammer.json
Any idea how? It needs to be relatively fast
EDIT: It'd also be cool if I could get the reason from the list, but that's not as necessary
https://lodash.com/docs/#find
Use lodash _.find to
const uuid = '000c97aaf948417a9a74d6858c01aaae'; // uuid you want to find
const scammer = _.find(scammersList, o => o.uuid === uuid);
if (scammer) { // if scammer found
console.log(scammer);
console.log(scammer.reason)
}
For anyone wondering, this is how I solved it:
async function checkPlayerScam(ign) {
const UUID = await getUUID(ign);
const response = await fetch(`https://raw.githubusercontent.com/skyblockz/pricecheckbot/master/scammer.json`);
const result = await responsejson();
if (result[UUID] = null) {
playerIsScammer == False
}
else{
playerIsScammer == True
}
}
This function will fetch the data, then check if the uuid 1d0c0ef4295047b39f0fa899c485bd00 exists. Assuming that you already fetched the data somewhere else and stored it, all you need to do is check if a given uuid exists by adding the following line where you please:
!!data[uuidToCheck]
uuidToCheck should be the uuid string that you are looking for.
This line will return true if the uuid exists and false otherwise.
In terms of the spacetime complexity, this function runs in constant time [O(1)] and O(N) space. This is the fastest time you can get it to run.
data[uuidToCheck].reason will return the reason.
async function playerIsScammer(uuidToCheck) {
uuidToCheck = '1d0c0ef4295047b39f0fa899c485bd00';
const response = await fetch('https://raw.githubusercontent.com/skyblockz/pricecheckbot/master/scammer.json');
if (response.ok){
let data = await response.json();
if(!!data[uuidToCheck])
return data[uuidToCheck].reason;
return false
}
}
I am implementing a cacheing layer in NodeJS and MongoDB using Redis. I am fairly new to Redis. So I am having trouble where I am trying to automatically clear cache after a given timing. The error I am getting
ReplyError: ERR wrong number of arguments for 'hset' command
This is my code block
mongoose.Query.prototype.exec = async function() {
const key = JSON.stringify(
Object.assign({}, this.getQuery(), {collection:
this.mongooseCollection.name})
);
const cachedValue = await client.hget(this.hashKey, key);
if(cachedValue) {
const parsedDoc = JSON.parse(cachedValue);
return Array.isArray(parsedDoc) ? parsedDoc.map(doc => new
this.model(doc)) : new this.model(parsedDoc);
}
const result = await exec.apply(this, arguments);
client.hset(this.hashKey, key, JSON.stringify(result), 'EX', 10);
return result;
}
Redis HSET only accepts 3 arguments. If you want to store multiple keys in one call, you should use HMSET.
Reference:
https://redis.io/commands/hset
https://redis.io/commands/hmset
client.hmset(this.hashKey, key, JSON.stringify(result), 'EX', 10);
should work.
I am facing the problem of clone of the mongoose query object .Javascript the copy the one object into another object by call-by-ref but in my project there is scenario i need to copy one object into another object by call-by-value.
var query=domain.User.find({
deleted: false,
role: role
})
var query1=query;
I have the scenario change in the query object is not reflected in query1. I google and try so many way to clone the object but it does't work.The query object is used in another function for pagination and query1 object is used for count query.
1.I used to Object.clone(query1) error Object.clone is not function
2.I used Object.assign(query1) but it does't works fine.
3.I used other so many ways can anybody help me to sort this problem
Alternative solution using merge method:
const query = domain.User.find({
deleted: false,
role: role
}).skip(10).limit(10)
const countQuery = query.model.find().merge(query).skip(0).limit(0)
const [users, count] = await Promise.all([query, countQuery.count()])
you are trying to clone a cursor, but it is not the right approach, you probably just need to create another
like this:
var buildQuery = function() {
return domain.User.find({
deleted: false,
role: role
});
};
var query = buildQuery();
var query1 = buildQuery();
This is work for me:
const qc = sourceQuery.toConstructor();
const clonedQuery = new qc();
This code work in pagination function where sourceQuery passed as parameter and i dont known what models used. Also it work with aggregations and complex queries.
public async paging(
query: mongoose.DocumentQuery<mongoose.Document[], mongoose.Document>,
params,
transformer: any = null
) {
let page = Number(params.page);
if (!page) page = 1;
let page_size = Number(params.count);
if (!page_size) page_size = 100;
const qc = query.toConstructor();
const cq = new qc();
return cq.countDocuments().exec()
.then(async (total) => {
const s = params.sort;
if (s) {
query.sort(s);
}
query.limit(page_size);
query.skip(page_size * (page - 1));
let results = await query.exec();
if (transformer) {
results = await Promise.all(results.map((i) => transformer(i)));
}
const r = new DtoCollection();
r.pages = Math.ceil(total / page_size);
r.total = total;
(r.results as any) = results;
return r;
});
}
Sergii Stotskyi's answer works just fine and is very elegant, except that count is deprecated.
countDocuments or estimatedDocumentCount should be used instead.
However, this causes the error the limit must be positive. We can walk around this by set limit to a large integer.
const query = domain.User.find({
deleted: false,
role: role
}).skip(10).limit(10)
const countQuery = query.model.find().merge(query).skip(0).limit(Number.MAX_SAFE_INTEGER)
const [users, count] = await Promise.all([query, countQuery.countDocuments()])
Since mongoose v6 you can use Query.prototype.clone
E.g. for your code snippet:
const query = domain.User.find({
deleted: false,
role: role
})
const query1 = query.clone();