Search for multiple word uisng postgres and javascript - javascript

I want to search for multiple words using this query below. when i search for 'document role' I should get all documents that have all document and all document that has role in it using sequelize
function searchDocuments(req, res) {
const limit = req.query.limit || 6,
offset = req.query.offset || 0,
queryString = req.query.q,
splitString = queryString.split(' ');
let querySearch = '';
splitString.forEach((query, index, initial) => {
console.log(initial[index]);
});
if (!queryString) {
return res.status(400).json({
message: 'Invalid search input'
});
}
if (req.decoded.roleId === 1) {
return Document.findAndCountAll({
limit,
offset,
where: {
title: {
$iLike: `%${querySearch}%`
}
},
include: [
{
model: User,
attributes: ['userName', 'roleId']
}
]
})
.then(({ rows: document, count }) => {
if (count === 0) {
return res.status(404).json({
message: 'Search term does not match any document.'
});
}
res.status(200).send({
document,
pagination: pagination(count, limit, offset),
});
})
.catch(error => res.status(400).send(error));
I just want a sequelize query that perform does an OR task with the keyword of title

From the top add the following code:
const limit = req.query.limit || 6,
offset = req.query.offset || 0,
queryString = req.query.q.replace(/ +(?= )/g, ''),
searchQuery = [];
if (!queryString) {
return res.status(400).json({
message: 'Invalid search input'
});
}
if (req.decoded.roleId === 1) {
const splitString = queryString.trim().split(' ');
splitString.forEach((query) => {
const output = { $iLike: `%${query}%` };
searchQuery.push(output);
});
Then add the following where you are querying searchQuery:
where: {
title: {
$or: searchQuery
}
}

Related

Supabase PGRST102 - Error All object keys must match

Can you help me?
I have a problem that I don't know how to solve or why it is happening.
I am consuming an api from nodejs to obtain certain data and as I am obtaining it, I am storing it in Supabase to obtain it, until I form my information object as I need it.
The problem is that when I want to update a table in supabase it throws me the error "All object keys must match", doing some research I found a forum that mentioned that maybe it was because the primary identifier was null, but I made sure by checking data by data . Then according to the PostgreeSQL error code "PGRST102" it is because the body that was sent in the request is not valid.
So my question is why can't I save my array object to my table? What am I doing wrong?
export const summaryActivity = async(req: Request & any, res: Response) => {
let supabase = instanceSupabase();
try {
// get the ID of the organization (important parameter to query data)
const {
data: organization,
error: organizationError
} = await supabase.from('organization').select('id');
const organizationID = organization ? .map(id => id ? .id).toString();
if (!organizationID) {
return res.status(403).json({
error: true,
message: 'ID de la organización indefinido'
});
}
// query between range date
const date_start = req.query.date_start ? moment.utc(req.query.date_start).startOf('day').toDate().toISOString() : moment().toDate().toISOString();
const date_end = req.query.date_end ? moment.utc(req.query.date_end).endOf('day').toDate().toISOString() : moment().toDate().toISOString();
if (!date_start || !date_end) {
return res.status(403).json({
error: true,
message: 'Date Inválid'
});
}
// consulted in API the hours worked of the day
const activitiesDailyURL = process.env.API_BASE_URL + `v2/organizations/${organizationID}/activities/daily?page_limit=300&date[start]=${date_start}&date[stop]=${date_end}`;
const activitiesDailyrequest = await req.app.authClient!.requestResource(activitiesDailyURL, req.app.session);
// convert response to json
const bodyActivitiesDaily = activitiesDailyrequest ? .body;
const convertactivitiesDaily = JSON.parse(bodyActivitiesDaily.toString());
const activitiesDaily: DailyActivityData = convertactivitiesDaily;
if (!activitiesDaily) {
return res.status(403).json({
error: true,
message: 'Something wrong'
});
}
// consulting the Projects table and obtaining the relationship projects x clients
const {
data: projectClients,
error: projectError
} = await supabase.from('projects').select('project_id, name, status, clients ( client_id, name, status )');
if (projectError) {
return res.status(403).json({
error: true,
message: 'Relacion Entidad Proyecto Inválido',
projectError
});
}
// filtering two objects to perform the union of them
const joinProject = activitiesDaily.daily_activities.map(item => {
const obj1Item = projectClients ? .filter(element => item.project_id === element ? .project_id);
return obj1Item ? { ...item,
...obj1Item
} : { ...item
}
});
if (!joinProject) {
res.json("Wrong to join project")
}
// consulting the users table (bring only the DEV, SAC, DESIGN roles)
const {
data: user,
error: userError
} = await supabase.from('user').select('user_id, username, status, daily_hours, rol').in('rol', ['DEV', 'SAC', 'DESIGN']);
if (userError) {
return res.status(403).json({
error: true,
message: 'Relation Entity User Invalid!',
userError
});
}
// filtering user data response with joinProjects to perform the union of them
const joinUser = joinProject ? .map(item => {
const obj1Item = user ? .find(element => item.user_id === element ? .user_id);
return obj1Item ? { ...item,
...obj1Item
} : { ...item
}
});
if (!joinUser) {
return res.status(403).json({
error: true,
message: 'Relation Entity Project Invalid',
userError
});
}
// iterating over the joinUser object to filter data for the same user
let summedTracked = joinUser.reduce((acc, c) => {
let filtered = acc.filter((el: DailyActivityJoin) => el ? .user_id === c ? .user_id);
if (filtered.length > 0) {
acc[acc.indexOf(filtered[0])].tracked += +c.tracked;
acc[acc.indexOf(filtered[0])].overall += +c.overall;
acc[acc.indexOf(filtered[0])].keyboard += +c.keyboard;
acc[acc.indexOf(filtered[0])].input_tracked += +c.input_tracked;
acc[acc.indexOf(filtered[0])].mouse += +c.mouse;
acc[acc.indexOf(filtered[0])].billable += +c.billable;
acc[acc.indexOf(filtered[0])].manual += +c.manual;
acc[acc.indexOf(filtered[0])].idle += +c.idle;
acc[acc.indexOf(filtered[0])].resumed += +c.resumed;
} else {
acc.push(c);
}
return acc;
}, []);
// types of summedTracked
const convertObject: DailyActivityJoin[] = summedTracked;
const newArr: any[] = [];
// map convertObject to create a new array where new items will be passed with the corresponding calculations
convertObject.map(element => {
let range = {
min: 10000,
max: 99999
}
let delta = range.max - range.min
const rand = Math.round(range.min + Math.random() * delta);
const overall = element.overall;
const tracked = element.tracked;
const dayliHours = element.daily_hours
const calculatedActivity = (overall / tracked) * 100;
const totalHoursTracked = (tracked / 3600);
const percentHours = (totalHoursTracked / dayliHours) * 100;
newArr.push({
activityid: rand,
id: element.id,
date: element.date,
user_id: element.user_id,
project_id: element.project_id,
task_id: element.task_id,
keyboard: element.keyboard,
mouse: element.mouse,
overall: element.overall,
tracked: element.tracked,
input_tracked: element.input_tracked,
manual: element.manual,
idle: element.idle,
resumed: element.resumed,
billable: element.billable,
created_at: element.created_at,
updated_at: element.updated_at,
username: element.username,
status: element.status,
daily_hours: element.daily_hours,
rol: element.rol,
"0": element[0],
percentActivity: Math.round(calculatedActivity),
hoursTracked: totalHoursTracked.toFixed(2),
percentHours: Math.round(percentHours),
createRegister: moment().format('YYYY-MM-DD[T]HH:mm:ss.SSS[Z]')
});
});
if (!newArr) {
return res.status(403).json({
error: true,
message: 'Seguimiento de la actividad del usuario indefinido',
userError
});
}
console.log(newArr);
// Find the activity-historic-tracked table within an array of unique ids if they already exist within it
const findId = newArr.map(id => id ? .id);
const {
data: record,
error: errorHistoric
} = await supabase.from('activity-historic-tracked').select('*').in('id', findId)
if (errorHistoric) {
res.json({
error: true,
message: 'Something wrong!',
errorHistoric
})
}
// If it doesn't exist
if (record ? .length !== 0) {
// doSomething...
} else {
// Otherwise update the activity-historic-tracked table
const {
data: historicoActividad,
error: recordError
} = await supabase.from('activity-historic-tracked').upsert(newArr);
if (recordError) {
return res.status(403).json({
error: true,
message: 'Error in upsert',
recordError
});
}
res.status(201).json(historicoActividad);
} catch (error) {
res.status(500).json({
title: 'API Error',
message: 'Internal Server Error'
});
}
}
I also leave you the structure of my table in Supabase
Table
identity primary key historic_id
numerical identification
activity ID int8
date text
user_id int8
project_id int8
task_id int8
int8 keyboard
int8 mouse
traced int8
input_tracked int8
manual int8
idle int8
resume int8
billable int8
text created_in
updated text_in
username text
status text
daily_hours int8
rol text
percentActivity float8
hoursTracked float8
percentHours float8
createregister date
"0" json

why does my cloud function keep giving an error (CloudFirestore with ForOf Loop)?

My function getDocuments() in summary consists in that I pass some parameters in an array (like the path, the name of the document, if I want to section it by parts) and based on that array I return the content of each document through a loop (ForOf), the function I do it more than anything to save me too many lines of code, the problem is that it always throws me an error that I do not know what it is.
Can you help me? Please
Cloud function
export const employees = functions.https.onRequest((request, response) => {
corsHandler(request, response, async () => {
return await security.securityLayer(
{ _definedMethod: "GET", userValue: request.method },
{ _definedType: true, _definedLevel: [4], _definedSeconds: 12, userToken: request.header("_token") },
{ required: false },
{ required: false }
).then(async (answer) => {
if (answer.status === 400 || answer.status === 401) {
return response.status(answer.status).send(answer);
}
return await security.getDocuments([
{ collection: "Core/", documentName: "Centers", options: { idReturn: "centros", nestedProperties: [] } },
{
collection: "Core/", documentName: "Employees", options: {
idReturn: "personal",
nestedProperties: [
{ idReturn: "employees", name: "employee" },
{ idReturn: "submanager", name: "submanager" },
{ idReturn: "manager", name: "manager" }
],
},
},
], SPECIAL_CODE).then((documents) => response.status(documents.status).send(documents))
.catch(() => response.status(500).send(security.error500(SPECIAL_CODE, 2)));
}).catch(() => response.status(500).send(security.error500("SPECIAL_CODE", 1)));
});
});
async function
export async function getDocuments(
documents: {
collection: string,
documentName: string,
options: {
idReturn: string,
nestedProperties: {
idReturn: string,
name: string
}[]
}
}[],
code: string):
Promise<{ status: 201, code: string, subcode: number, devDescription: string, data: any }> {
const data: any = {};
const response: { devDescription: string, subcode: number } = { devDescription: "The document was found and retrieved successfully.", subcode: 1 };
if (documents.length > 1) {
response.devDescription = "Documents were found and obtained successfully.";
response.subcode = 2;
}
for (const iterator of documents) {
const docRef = { path: iterator.collection, name: iterator.documentName };
const options = { id: iterator.options.idReturn, nestedProperties: iterator.options.nestedProperties };
const doc = await database.collection(docRef.path).doc(docRef.name).get();
if (!doc.exists) {
data[options.id] = "The document " + docRef.name + " does not exist in the specified path: " + docRef.path;
if (documents.length === 1) {
response.devDescription = "The document was not found. Check the DATA for more information.";
response.subcode = 3;
} else {
response.devDescription = "One, several or all documents were not found. Check the DATA for more information.";
response.subcode = 3;
}
} else {
const docData: any = doc.data();
if (options.nestedProperties.length === 0) {
data[options.id] = docData;
} else {
for (const nested of options.nestedProperties) {
data[options.id][nested.idReturn] = _.get(docData, nested.name);
}
}
}
}
return { status: 201, code: code, subcode: response.subcode, devDescription: response.devDescription, data: data };
}
I was investigating and I saw that what was causing the error was obviously the loop (ForOf), to solve it I used the Promise.all() method, so the actual code that works for me is the following
export async function getDocuments(
documents: {
collection: string,
documentName: string,
path?: string,
options: {
idReturn: string,
nestedProperties: {
idReturn: string,
name: string
}[]
}
}[],
code: string):
Promise<{ status: number, code: string, subcode: number, devDescription: string, data: any }> {
const idPrimary: any = Object.values(
documents.reduce((c: any, v: any) => {
const k = v.options.idReturn;
c[k] = c[k] || [];
c[k].push(v);
return c;
}, {})
).reduce((c: any, v: any) => (v.length > 1 ? c.concat(v) : c), []);
if (idPrimary.length > 0) {
return {
status: 400, code: code, subcode: 0, data: idPrimary,
devDescription: "Some return IDs are repeated, check your code and replace the return IDs with unique IDs, for more information see the DATA section." };
}
const response: { devDescription: string, subcode: number } = { devDescription: "The document was found and retrieved successfully.", subcode: 1 };
const queries = [];
if (documents.length > 1) {
response.devDescription = "Documents were found and obtained successfully.";
response.subcode = 2;
}
documents.map((document) => {
if (document.path === undefined) {
document.path = document.collection + "/" + document.documentName;
}
});
for (const iterator of documents) {
queries.push(database.collection(iterator.collection).doc(iterator.documentName).get());
}
return Promise.all(queries).then((snapShot) => {
const data: any = {};
snapShot.forEach((doc) => {
const docProperties = documents.find((item) => item.path === doc.ref.path) ?? null;
if (!doc.exists) {
if (docProperties !== null) {
data[docProperties.options.idReturn] = "The document " + doc.id + " does not exist in the specified path: " + doc.ref.path;
if (documents.length === 1) {
response.devDescription = "The document was not found. Check the DATA for more information.";
response.subcode = 3;
} else {
response.devDescription = "One, several or all documents were not found. Check the DATA for more information.";
response.subcode = 3;
}
}
} else {
if (docProperties !== null) {
const docData: any = doc.data();
if (docProperties.options.nestedProperties.length === 0) {
data[docProperties.options.idReturn] = docData;
} else {
data[docProperties.options.idReturn] = {};
for (const nested of docProperties.options.nestedProperties) {
if (nested.name === undefined) {
data[docProperties.options.idReturn][nested.idReturn] = _.get(docData, nested.idReturn);
} else {
data[docProperties.options.idReturn][nested.idReturn] = _.get(docData, nested.name);
}
}
}
}
}
});
return { status: 201, code: code, subcode: response.subcode, devDescription: response.devDescription, data: data };
});
}

Want to update MongoDB with data that does not include objects that include the paid: true key/value

Good Evening,
I am using the MERN stack to create an application. I am using the Stripe API to gather invoices and save some information about the invoice in MongoDB. Right now I have a function that updates my DB with any object that does not exist and I have a delete function that deletes any documents in my DB that have the paid: true. when an invoice is paid Stripe marks it paid, when its paid I want to delete it from my DB. What happens now is that I delete it and then update function runs and just puts it right back.
The data in my DB and from stripe are an array of objects:
DB Sample:
[
{
Id: String,
created: Number,
customer_email: String,
customer_name: String,
due_date: Number,
hosted_invoice_url: String,
paid: Boolean
}
]
Codebase functions:
// Update and store function
async function saveInvoice(stripeInvoice) {
const condition = {id: stripeInvoice.id};
const query = {
id: stripeInvoice.id,
created: stripeInvoice.created,
customer_email: stripeInvoice.customer_email,
customer_name: stripeInvoice.customer_name,
due_date: stripeInvoice.due_date,
hosted_invoice_url: stripeInvoice.hosted_invoice_url,
paid: stripeInvoice.paid,
};
const options = { upsert: true };
const update = await InvoiceModel.updateMany(condition, query, options).catch((e) => {console.log(e)});
if(update.nModified > 0 ) {
console.log('Number of Invoices added or updated to DB:', update.nModified)
}
}
// Find common ID
function findCommoneID(stripeInvoice, DBInvoices) {
var isSame = true;
if(DBInvoices.length <= 0 || stripeInvoice.length <= 0) {
console.log('An Error has occured with Database or Stripe Data')
return isSame = false;
} else {
stripeInvoice.forEach((StripeElement) => {
DBInvoices.forEach((DBElement) => {
if(StripeElement.id !== DBElement.id) {
saveInvoice(StripeElement, DBElement);
isSame = false;
}
})
});
}
console.log('IDS match')
return isSame;
}
// Delete Function
async function deletePaidInvoicesFromDB(dbInvoices) {
for(let i = 0; i < dbInvoices.length; i++) {
if(dbInvoices[i].paid === true ) {
console.log(dbInvoices[i].id);
const deletedInvoices = await InvoiceModel.deleteMany({paid: true});
console.log(deletedInvoices.deletedCount)
break;
}
}
}
The save function takes in the data gathered from the findCommonId() function and if the id doesn't exist it adds the stripe object to the DB.
// Save Function
async function saveInvoice(stripeInvoice) {
if(stripeInvoice.paid === true) {
return;
} else {
const condition = {id: stripeInvoice.id};
const query = {
id: stripeInvoice.id,
amount_due: stripeInvoice.amount_due,
created: stripeInvoice.created,
customer_email: stripeInvoice.customer_email,
customer_name: stripeInvoice.customer_name,
due_date: stripeInvoice.due_date,
hosted_invoice_url: stripeInvoice.hosted_invoice_url,
paid: stripeInvoice.paid,
};
const options = { upsert: true };
const update = await InvoiceModel.updateMany(condition, query, options).catch((e) => {console.log(e)});
if(update.nModified > 0 ) {
console.log('Number of Invoices added or updated to DB:', update.nModified)
}
}
}
// findCommoneId
function findCommoneID(stripeInvoice, DBInvoices) {
if(DBInvoices.length <= 0 || stripeInvoice.length <= 0) {
InvoiceModel.create(stripeInvoice, () => {console.log('Invoices saved to database')});
console.log('An Error has occured with Database or Stripe Data')
stripeInvoice.forEach((StripeElement) => {
if(StripeElement.paid === true) {
return;
}
})
stripeInvoice.forEach((StripeElement) => {
DBInvoices.forEach((DBElement) => {
if(StripeElement.id !== DBElement.id) {
saveInvoice(StripeElement);
}
})
});
}
console.log('IDS match')
}

map() in node.js, async vs sync?

I have a segment code like below running in Node.js. And I find it will always goes to else condiction, howerver with masterData is not null.
getOperationDetails(req, res) {
let sql = 'select a.*, b.s*';
sql += ` from ${paymentSheet} a left join ${paymentHisSheet} b on a.id= b.source_id `;
sql += ' where a.id=? ';
func.connPool(sql, id, (err, rows, field) => {
if (err) {
res.json({ code: 400, message: err })
} else {
let masterData = [];
let details = rows.map((row, idx) => {
if (idx === 0) {
masterData.push({
id: row.id,
name: row.name
});
}
return {
operator: row.operator_info,
comments: row.cmt,
status: row.sta
}
})
if (masterData.length > 0 ) {
masterData[0].details = details;
} else {
console.log(sql);
console.log(id);
console.log('=======================');
console.log(masterData);
}
res.json({ code: 200, message: 'ok', data: masterData })
}
})
For example, the console will show like below. Obviously masterData has value. It means 'if' condiction run before map(). Do I have to use async to wait the map() handle the data over?
allConnections:2
select a.*, b.* from payment a left join history b on a.id= b.source_id where a.id=?
83e588cd-9b4b-4592-ac7f-529bfaa9b231
=======================
allConnections:2
allConnections:2
[
{
id: '83e588cd-9b4b-4592-ac7f-529bfaa9b231',
name: 'Jeff'
}
]
My anaysis:
the rows from database should like below
83e588cd-9b4b-4592-ac7f-529bfaa9b231', 'Jeff', 'Operator Peter', 'OK', 0
83e588cd-9b4b-4592-ac7f-529bfaa9b231', 'Jeff', 'Operator Mary', 'NO', 1
83e588cd-9b4b-4592-ac7f-529bfaa9b231', 'Jeff', 'Operator Jet', 'OK', 2
or like below, means no details
83e588cd-9b4b-4592-ac7f-529bfaa9b231', 'Jeff', null, null, null
That is why I use masterData to separate. I think push() should not be taken out the map(), becasue rows maybe return nothing. Will it be like map() is over and push() is still running?
==== P.S. func.connPool====
let mysql = require('mysql');
let db = require('../configs/db');
let pool = mysql.createPool(db);
module.exports = {
connPool (sql, val, cb) {
pool.getConnection((err, conn) => {
if (err) {
console.log('Connection Error:' + err);
cb(err, null, null);
} else {
console.log('allConnections:' + pool._allConnections.length);
let q = conn.query(sql, val, (err, rows,fields) => {
pool.releaseConnection(conn);
if (err) {
console.log('Query:' + sql + ' error:' + err);
}
cb(err, rows, fields);
});
}
});
},
What I suspected is that the push operation is somehow delay because of some code that is not shown here (I am not certain yet).
I ran the following code so many times, I still could not reproduce your problem.
var rows = [
{
id: "123",
name: "test",
},
{
id: "123",
name: "test",
},
{
id: "123",
name: "test",
},
]
let masterData = [];
let details = rows.map((row, idx) => {
if (idx === 0) {
masterData.push({
id: row.id,
name: row.name
});
}
return {
id: row.id,
name: row.name,
}
})
if (masterData.length > 0 ) {
console.log("in");
} else {
console.log(masterData);
console.log('=======================');
}
Could you try whether it goes to else or not for this code.
From this piece of code you are pushing to MasterData only the first row.id and row.name.
( that is specified in the if conditional for just the first index idx === 0 )
So if thats the case you don't need to have this push thing inside the map.
You can take that out of the map and leave the iterator to create only the details array.
You can go with:
let details = rows.map(row => ({
operator: row.operator_info,
comments: row.cmt,
status: row.sta
})
);
let masterData = [{ id: rows[0].id, name: rows[0].name, details }]

Firebase database how to list

I am trying to query a Firebase database. I have the following code, but it returns an empty list, when there is matching data.
loadData() {
this.firelist = this.af.database.list('/chat/', {
query: {
orderByChild: 'negativtimestamp'
}
}).map(items => {
const filtered = items.filter(item => {
item.memberId1 === this.me.uid;
});
return filtered;
});
// if me not in firelist then create new chat
if (this.me && this.me.uid) {
let chatFound: boolean = false;
console.log('this.firelist', this.firelist);
this.firelist.forEach(chatItems => {
console.log('chatItems', chatItems);
for (let i = 0; i < chatItems.length; i++) {
console.log('chatItems['+i+']', chatItems[i]);
let memberId1: string = chatItems[i].memberId1;
let memberId2: string = chatItems[i].memberId2;
if (memberId1 === this.me.uid || memberId2 === this.me.uid) {
chatFound = true;
break;
}
}
if (!chatFound) {
//this.createChat();
}
});
}
}
I think my problem is with the filter.
The following code creates a chat successfully:
createChat(img1: string, img2: string) {
this.af.database.list('/chat/').push({
memberId1: this.me.uid,
memberId2: this.you.uid,
img1: img1,
img2: img2,
displayName1: this.me.displayName,
displayName2: this.you.displayName,
lastMsg_text: 'todo',
timestamp: Date.now(),
negativtimestamp: -Date.now()
})
}
The following filter works:
this.firelist = this.af.database.list('/chat/', {
query: {
orderByChild: 'negativtimestamp'
}
}).map(items => {
const filtered = items.filter(
item => item.memberId1 === this.me.uid
);
return filtered;
});

Categories

Resources