Search Operators in Sequelize - javascript

I wanted to display all of the data which have gains of greater than 1. But I seem to encounter problems on running the request on my postman with the url of :
http://localhost:3000/api/betHistory/winners
I get the result of:
Executing (default): SELECT `id`, `user_id`, `type`, `league_id`, `team_id`, `amount`, `gains`, `ratio`, `match_id`, `created_at`, `updated_at`, `updatedAt` FROM `bets` AS `bets` WHERE `bets`.`gains` = false;
which should be 'gains' '>' '1'
This is my bet.js
router.get('/winners', async (req, res) => {
try {
const data = req.params.gains;
const bets = await BetRepository.getWinnersBets(data > 1);
res.json(bets);
} catch (error) {
res.status(400).send('No data found');
}
});
This is my BaseRepistory.js
findAll(fields) {
const options = {};
if (!!fields && fields) {
options.attributes = fields;
}
return this.model.findAll(options);
}
And this is my BetRepository.js
const BaseRepository = require('../../../shared/repository/BaseRepository');
const Bet = require('../models/Bet');
const Op = require('sequelize').Op;
class BetRepository extends BaseRepository {
constructor(model) {
super(model);
}
getWinnersBets(gains, fields) {
const options = {
where: { gains }
};
if (!!fields && fields) {
options.attributes = fields;
}
return this.model.findAll(options);
}
}
module.exports = new BetRepository(Bet);
Any ideas on how to work with this? TYIA.

When you do getWinnersBets(data > 1);, you are not passing the expression data > 1 to getWinnersBets, you are passing getWinnersBets(true) or getWinnersBets(false) to it, so in your query you are actually querying
'gains' '=' 'true'
and not
'gains' '>' '1'
I don't know the API of model.findAll so I can't give you a pointer on how to pass that expression to findAll

I have solved this problem by putting an operator on my getWinnersBets
getWinnersBets(fields) {
const options = {
where: {
gains: {
[Op.gte]: 1
}
}
};
if (!!fields && fields) {
options.attributes = fields;
}
return this.model.findAll(options);
}
and removed the > 1 line on my const bets = await BetRepository.getWinnersBets(data > 1)

Related

Building a criteria in mongoDB that doesn't return the proper values

I'm trying to builda criteria that would filter the entries in the DB ,yet i'm not getting the proper results when filtering the genre. (the text seems to work but i'm not sure if the code will support both filters).
This is my buildCriteria function, console logging returns the proper values.
function _buildCriteria(filterBy) {
const criteria = {};
const { text, genre } = filterBy;
console.log('genre:', genre);
if (text) {
const txtCriteria = { $regex: text, $options: 'i' };
criteria.name = txtCriteria;
}
if (genre) {
criteria.genre = { $eq: genre };
}
return criteria;
}
This is the query function :
async function query(filterBy) {
try {
const criteria = _buildCriteria(filterBy);
const collection = await dbService.getCollection('tab');
const tabs = await collection.find(criteria).toArray();
return tabs;
} catch (err) {
logger.error('Can not find tabs', err);
throw err;
}
}
Would appreciate your help greatly!

Algolia - get mass records & delete with filter

I am using Algolia for search purposes and we got a huge pile of records. We want to delete some records and have decided to delete records that are older than X date.
First I was using this
const records = [];
const deleteRecordsBeforeDateAlgolia = (date) => {
let client;
*****
const index = client.initIndex('function_message');
//get the records before the given date
try {
index.search('',{
filters: `time_stamp < ${date}`
}).then(({hits}) => {
if(hits.length > 0) {
for (const hit of hits) {
index.deleteObject(hit.objectID);
records.push(hit.objectID);
}
}
if(hits.length === 0) {
console.log(`Deleted ${records.length} records`);
} else {
deleteRecordsBeforeDateAlgolia(date);
}
});
} catch (err) {
console.error(err);
}
};
but I realized this isnt that optimized + will be very slow when deleting on prod. Can you tell me how I can get huge amounts of data with a filter (timestamp in this case) and then delete all of them?
EDIT
const records = [];
const deleteRecordsBeforeDateAlgolia = (date) => {
let client;
//creds stuff
const index = client.initIndex('function_message');
//get the records before the given date
try {
const search = index.browseObjects({
filters: `time_stamp < ${date}`
}).then(res => {
//IT SHOWS RESPONSE IS UNDEFINED
res.forEach(record => {
records.push(record);
});
console.log(`found ${records.length} records`);
});
} catch (err) {
console.error(err);
}
};
browseObjects takes a batch callback function that's called on every batch of hits where you can specify what to do with the batch. The optional parameter list can be found here
Something like this should work
const records = [];
const deleteFromIndex = (idArray,index) => {
index.deleteObjects(idArray).then(({ objectIDs }) => {
console.log(objectIDs);
});
}
const deleteRecordsBeforeDateAlgolia = (date) => {
let client;
client = algoliasearch('algoliaApp', 'algoliaKey');
const index = client.initIndex('function_message');
try {
index.browseObjects({
filters: `time_stamp<${date}`,
query: '',
batch: (batch) => {
records.push(...batch); //push each batch into records array
}
})
.then(() => {
const idArray = records.map(({objectID}) => objectID) //get an array of objectIDs
deleteFromIndex(idArray, index)
});
} catch (err) {
console.error(err);
}
};
deleteRecordsBeforeDateAlgolia('some date')

Subquery returning no results when written as a function in TypeORM

I have a huge query that consists of 2 subqueries. Since I intend to use the subqueries at multiple places, I wanted to extract it as a function.
Here is the original query that works perfectly fine and returns expected results:
public async findUsers(): Promise<UserEntity[]> {
return this.createQueryBuilder('users')
.andWhere('users.user_type = :userType', { userType: UserType.Parent })
.andWhere(qb => {
const subquery = qb
.subQuery()
.select('COUNT(*)')
.from(EventEntity, 'e')
.where('e.object_id = users.member_id')
.andWhere('e.event_type = :eventType', { eventType: EventType.LOGIN })
.getQuery();
return subquery + '= 0';
})
.andWhere(qb => {
const subquery = qb
.subQuery()
.select('COUNT(*)')
.from(UserEntity, 'u1')
.where('u1.primary_Id = users.member_id')
.andWhere('u1.user_type = :userTypeChild', { userTypeChild: UserType.Child })
.getQuery();
return subquery + '= 0';
})
.getMany();
}
However, when I try to put the subquery inside a function, it returns no results. Here is the query:
public async findUsers(): Promise<UserEntity[]> {
return this.createQueryBuilder('users')
.andWhere('users.user_type = :userType', { userType: UserType.Parent })
.andWhere(`(${this.subquerysql()}) = 0`)
.andWhere(qb => {
const subquery = qb
.subQuery()
.select('COUNT(*)')
.from(UserEntity, 'u1')
.where('u1.primary_Id = users.member_id')
.andWhere('u1.user_type = :userTypeChild', { userTypeChild: UserType.Child })
.getQuery();
return subquery + '= 0';
})
.getMany();
}
private subquerysql(): string {
const query = getConnection()
.createQueryBuilder()
.select('COUNT(*)')
.from(EventEntity, 'e')
.innerJoin('users', 'u','e.object_id = u.member_id')
.andWhere(`e.event_type = 'LOGIN'`)
.getSql();
return query;
}
I can't seem to figure why the query isn't working(when I put subquery inside a function). I am writing this inside userRepository

How to move the code to set ut DB and collection out from my file and just requre it?

So, let's say I have this code that works perfectly.
const {
Database
} = require("arangojs");
var db = new Database({
url: "http://localhost:8529"
});
const database_name = "cool_database";
db.useBasicAuth("username", "password123");
db.listDatabases()
.then(names => {
if (names.indexOf(database_name) > -1) {
db.useDatabase(database_name);
db.get();
} else {
db.createDatabase(database_name)
.then(() => {
db.useDatabase(database_name);
db.collection("my-collection").create();
});
}
});
const collection = db.collection("my-collection");
const getJobFromQueue = () => {
return db.query({
query: "FOR el IN ##collection FILTER DATE_TIMESTAMP(el.email.sendAfter) < DATE_NOW() AND el.status != 'processed' AND el.status != 'failed' SORT el.email.sendAfter LIMIT 1 RETURN el",
bindVars: {
"#collection": "my-collection"
}
})
.then(cursor => cursor.all());
}
But I want to move the top code out to another file and just require db and collection, how do I make that work? Have been struggling to make it work for too long now.
const {
db,
collection
} = require("./db");
const getJobFromQueue = () => {
return db.query({
query: "FOR el IN ##collection FILTER DATE_TIMESTAMP(el.email.sendAfter) < DATE_NOW() AND el.status != 'processed' AND el.status != 'failed' SORT el.email.sendAfter LIMIT 1 RETURN el",
bindVars: {
"#collection": "my-collection"
}
})
.then(cursor => cursor.all());
}
just do exactly what you proposed. move the upper part of your code to db.js and expose dband collection using exports:
db.js:
const {
Database
} = require("arangojs");
var db = new Database({
url: "http://localhost:8529"
});
const database_name = "cool_database";
db.useBasicAuth("username", "password123");
db.listDatabases()
.then(names => {
if (names.indexOf(database_name) > -1) {
db.useDatabase(database_name);
db.get();
} else {
db.createDatabase(database_name)
.then(() => {
db.useDatabase(database_name);
db.collection("my-collection").create();
});
}
});
exports.collection = db.collection("my-collection");
exports.db = db;
index.js:
const {
db,
collection
} = require("./db");
const getJobFromQueue = () => {
return db.query({
query: "FOR el IN ##collection FILTER DATE_TIMESTAMP(el.email.sendAfter) < DATE_NOW() AND el.status != 'processed' AND el.status != 'failed' SORT el.email.sendAfter LIMIT 1 RETURN el",
bindVars: {
"#collection": "my-collection"
}
})
.then(cursor => cursor.all());
}
WARNING:
keep in mind, there is a potential race condition in your code. you may end up using db and collection, before they hat been initialized.

node-oracledb bind variable of null

Using the node-oracledb package with node.js, I'm trying to delete a row in my oracle database that has a null value in it. I need to be able to pass a null value in as a bind variable but it is throwing an error:
var query = "delete from table where event IS :event";
var bind_vars = [null];
connection.execute(query, bind_vars, { autoCommit: true }, function(error, results) {});
The error returned is
{ Error: ORA-00908: missing NULL keyword errorNum: 908, offset: 46 }
You don't need a bind variable for that...
Given the following table:
create table t (
c number
);
insert into t values (1);
insert into t values (null);
insert into t values (3);
insert into t values (null);
insert into t values (5);
commit;
This should work:
const oracledb = require('oracledb');
const config = require('./dbConfig.js');
async function runTest() {
let conn;
try {
conn = await oracledb.getConnection(config);
let result;
let value = 1;
if (value === null) {
result = await conn.execute('delete from t where c is null');
} else { // other values should have a bind
result = await conn.execute('delete from t where c = :value', [value]);
}
// Note that the work was not committed.
console.log('Rows deleted:', result.rowsAffected);
} catch (err) {
console.error(err);
} finally {
if (conn) {
try {
await conn.close();
} catch (err) {
console.error(err);
}
}
}
}
runTest();
what about change the query
var query = "delete from table where nvl(event, '__') = nvl(:event, '__')";
var bind_vars = [null];
connection.execute(query, bind_vars, { autoCommit: true }, function(error, results) {});
it change null column and value to another character
change (__) with your own character

Categories