From 57ce1ed6f98b71b7e3fbf78e371f3941e759b7f2 Mon Sep 17 00:00:00 2001 From: meek0 Date: Tue, 1 Oct 2024 16:36:49 -0400 Subject: [PATCH 1/3] fix: CLIN-3242 fix search by flag --- src/db/dal/variant.ts | 34 +++++++++++++++++----------------- src/db/models/Variant.ts | 3 +++ src/routes/variant.ts | 2 +- 3 files changed, 21 insertions(+), 18 deletions(-) diff --git a/src/db/dal/variant.ts b/src/db/dal/variant.ts index d37ce3d..28c1ca5 100644 --- a/src/db/dal/variant.ts +++ b/src/db/dal/variant.ts @@ -26,22 +26,22 @@ export const getEntriesByUniqueIdsAndOrganizations = async function (uniqueIds: } export const getEntriesByPropertiesFlags = async function (flags: string[], organizationIds: string[]) { - return await VariantModel.findAll({ - attributes: ['unique_id'], - group: ['unique_id'], - where: { - [Op.or]: flags.map(f => { - return { - properties: { - [Op.contains]: { - flags: [f] - } - } - }; - }), - organization_id: { - [Op.in]: organizationIds - } - } + const flagsWhere = flags.map(f => { + return `properties @> '{"flags": ["${f}"]}'`; }); + + const result = await VariantModel.sequelize.query(` + SELECT unique_id, timestamp, properties, rnk + FROM ( + SELECT + unique_id, + timestamp, + properties, + RANK() OVER (PARTITION BY unique_id ORDER BY timestamp DESC) AS rnk + FROM variants + WHERE organization_id IN ('${organizationIds.join("', '")}') + ) s + WHERE rnk = 1 AND (${flagsWhere.join(' OR ')});`); + + return result; } \ No newline at end of file diff --git a/src/db/models/Variant.ts b/src/db/models/Variant.ts index 315bf6e..8b631da 100644 --- a/src/db/models/Variant.ts +++ b/src/db/models/Variant.ts @@ -1,6 +1,9 @@ import { CreationOptional, DataTypes, Model, Optional } from 'sequelize'; import sequelizeConnection from '../config'; + +export const MISSING = '__missing__'; + interface IVariantAttributes { id: number; unique_id: string; diff --git a/src/routes/variant.ts b/src/routes/variant.ts index bf512e0..3026712 100644 --- a/src/routes/variant.ts +++ b/src/routes/variant.ts @@ -105,7 +105,7 @@ variantRouter.get('/filter', async (req, res, next) => { if (canGet && flags.length > 0) { dbResponse = await getEntriesByPropertiesFlags(flags, userInfo.userOrganizations); - return res.status(StatusCodes.OK).send(dbResponse.map(r => r.unique_id)); + return res.status(StatusCodes.OK).send(dbResponse[0].map(r => r.unique_id)); } else if (!canGet) { return res.sendStatus(StatusCodes.FORBIDDEN); } else { From 5a1991d217b6015f487c16a76ecf34e8c783e255 Mon Sep 17 00:00:00 2001 From: meek0 Date: Wed, 2 Oct 2024 09:16:45 -0400 Subject: [PATCH 2/3] fix: CLIN-3242 manage __missing__ --- src/db/dal/variant.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/db/dal/variant.ts b/src/db/dal/variant.ts index 28c1ca5..c1ddca9 100644 --- a/src/db/dal/variant.ts +++ b/src/db/dal/variant.ts @@ -1,5 +1,5 @@ -import { Op } from 'sequelize'; -import VariantModel from '../models/Variant'; +import { col, fn, Op, where } from 'sequelize'; +import VariantModel, { MISSING } from '../models/Variant'; export const addNewEntry = async function (uniqueId: string, organizationId: string, authorId: string, properties: any) { return await VariantModel.create({ @@ -27,7 +27,7 @@ export const getEntriesByUniqueIdsAndOrganizations = async function (uniqueIds: export const getEntriesByPropertiesFlags = async function (flags: string[], organizationIds: string[]) { const flagsWhere = flags.map(f => { - return `properties @> '{"flags": ["${f}"]}'`; + return f === MISSING ? `JSONB_ARRAY_LENGTH(properties -> 'flags') = 0` : `properties @> '{"flags": ["${f}"]}'`; }); const result = await VariantModel.sequelize.query(` From fbeb3691608e4e2fd3efd4b5c7f422b04690c8d0 Mon Sep 17 00:00:00 2001 From: meek0 Date: Wed, 2 Oct 2024 10:06:32 -0400 Subject: [PATCH 3/3] fix: CLIN-3242 __missing__ no longer used --- src/db/dal/variant.ts | 6 +++--- src/db/models/Variant.ts | 3 --- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/db/dal/variant.ts b/src/db/dal/variant.ts index c1ddca9..28c1ca5 100644 --- a/src/db/dal/variant.ts +++ b/src/db/dal/variant.ts @@ -1,5 +1,5 @@ -import { col, fn, Op, where } from 'sequelize'; -import VariantModel, { MISSING } from '../models/Variant'; +import { Op } from 'sequelize'; +import VariantModel from '../models/Variant'; export const addNewEntry = async function (uniqueId: string, organizationId: string, authorId: string, properties: any) { return await VariantModel.create({ @@ -27,7 +27,7 @@ export const getEntriesByUniqueIdsAndOrganizations = async function (uniqueIds: export const getEntriesByPropertiesFlags = async function (flags: string[], organizationIds: string[]) { const flagsWhere = flags.map(f => { - return f === MISSING ? `JSONB_ARRAY_LENGTH(properties -> 'flags') = 0` : `properties @> '{"flags": ["${f}"]}'`; + return `properties @> '{"flags": ["${f}"]}'`; }); const result = await VariantModel.sequelize.query(` diff --git a/src/db/models/Variant.ts b/src/db/models/Variant.ts index 8b631da..315bf6e 100644 --- a/src/db/models/Variant.ts +++ b/src/db/models/Variant.ts @@ -1,9 +1,6 @@ import { CreationOptional, DataTypes, Model, Optional } from 'sequelize'; import sequelizeConnection from '../config'; - -export const MISSING = '__missing__'; - interface IVariantAttributes { id: number; unique_id: string;