Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve global request performances #354

Merged
109 changes: 33 additions & 76 deletions apps/server/src/database/queries/album.ts
Original file line number Diff line number Diff line change
@@ -1,127 +1,84 @@
import { AlbumModel, InfosModel } from '../Models';
import { User } from '../schemas/user';
import { AlbumModel, InfosModel } from "../Models";
import { User } from "../schemas/user";

export const getAlbums = (albumsId: string[]) =>
AlbumModel.find({ id: { $in: albumsId } });

export const searchAlbum = (str: string) =>
AlbumModel.find({ name: { $regex: new RegExp(str, 'i') } });
AlbumModel.find({ name: { $regex: new RegExp(str, "i") } });

export const getAlbumInfos = (albumId: string) => [
{
$lookup: {
from: 'tracks',
let: { targetId: '$id' },
from: "tracks",
let: { targetId: "$id" },
pipeline: [
{
$match: {
$expr: {
$and: [
{ $eq: ['$album', albumId] },
{ $eq: ['$id', '$$targetId'] },
{ $eq: ["$album", albumId] },
{ $eq: ["$id", "$$targetId"] },
],
},
},
},
{ $project: { trackId: '$id', albumId: '$album' } },
{ $project: { trackId: "$id", albumId: "$album" } },
],
as: 'albumInfos',
}
as: "albumInfos",
},
},
{ $match: { 'albumInfos.albumId': { $exists: true } } },
{ $unwind: '$albumInfos' }
]
{ $match: { "albumInfos.albumId": { $exists: true } } },
{ $unwind: "$albumInfos" },
];

export const getFirstAndLastListenedAlbum = async (user: User, albumId: string) => {
export const getFirstAndLastListenedAlbum = async (
user: User,
albumId: string,
) => {
const res = await InfosModel.aggregate([
{ $match: { owner: user._id } },
{ $match: { owner: user._id, albumId: albumId } },
...getAlbumInfos(albumId),
{ $sort: { played_at: 1 } },
{
$group: {
_id: null,
first: { $first: '$$ROOT' },
last: { $last: '$$ROOT' },
first: { $first: "$$ROOT" },
last: { $last: "$$ROOT" },
},
},
...['first', 'last']
...["first", "last"]
.map(e => [
{
$lookup: {
from: 'tracks',
from: "tracks",
localField: `${e}.albumInfos.trackId`,
foreignField: 'id',
foreignField: "id",
as: `${e}.track`,
},
},
{ $unwind: `$${e}.track` }
{ $unwind: `$${e}.track` },
])
.flat(1),
]);
return res[0];
}
};

export const getAlbumSongs = async (user: User, albumId: string) => {
const res = await InfosModel.aggregate([
{ $match: { owner: user._id } },
{ $match: { owner: user._id, albumId: albumId } },
...getAlbumInfos(albumId),
{ $group: { _id: '$id', count: { $sum: 1 } } },
{ $group: { _id: "$id", count: { $sum: 1 } } },
{ $sort: { count: -1 } },
{
$lookup: {
from: 'tracks',
localField: '_id',
foreignField: 'id',
as: 'track',
from: "tracks",
localField: "_id",
foreignField: "id",
as: "track",
},
},
{ $unwind: '$track' },
{ $unwind: "$track" },
]);
return res;
}

export const getRankOfAlbum = async (user: User, albumId: string) => {
const res = await InfosModel.aggregate([
{ $match: { owner: user._id } },
{ $lookup: {
from: 'tracks',
localField: 'id',
foreignField: 'id',
as: 'track',
}},
{ $unwind: '$track' },
{ $group: {
_id: '$track.album',
count: { $sum: 1 }
}},
{ $sort: { count: -1, _id: 1 } },
{ $group: { _id: 1, array: { $push: { id: '$_id', count: '$count' } } } },
{
$project: {
index: {
$indexOfArray: ['$array.id', albumId],
},
array: 1,
},
},
{
$project: {
index: 1,
isMax: {
$cond: { if: { $eq: ['$index', 0] }, then: true, else: false },
},
isMin: {
$cond: {
if: { $eq: ['$index', { $subtract: [{ $size: '$array' }, 1] }] },
then: true,
else: false,
},
},
results: {
$slice: ['$array', { $max: [{ $subtract: ['$index', 1] }, 0] }, 3],
},
},
}
]);
return res[0];
}
};
78 changes: 16 additions & 62 deletions apps/server/src/database/queries/artist.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export const getArtistInfos = (artistId: string) => [
export const getFirstAndLastListened = async (user: User, artistId: string) => {
// Non sense to compute blacklist here
const res = await InfosModel.aggregate([
{ $match: { owner: user._id } },
{ $match: { owner: user._id, primaryArtistId: artistId } },
...getArtistInfos(artistId),
{ $sort: { played_at: 1 } },
{
Expand Down Expand Up @@ -79,7 +79,7 @@ export const getMostListenedSongOfArtist = async (
) => {
const res = await InfosModel.aggregate([
// Non sense to compute blacklist here
{ $match: { owner: user._id } },
{ $match: { owner: user._id, primaryArtistId: artistId } },
...getArtistInfos(artistId),
{ $group: { _id: "$id", count: { $sum: 1 } } },
{ $sort: { count: -1 } },
Expand Down Expand Up @@ -109,7 +109,7 @@ export const getMostListenedSongOfArtist = async (
export const bestPeriodOfArtist = async (user: User, artistId: string) => {
// Non sense to compute blacklist here
const res = await InfosModel.aggregate([
{ $match: { owner: user._id } },
{ $match: { owner: user._id, primaryArtistId: artistId } },
...getArtistInfos(artistId),
{
$project: {
Expand Down Expand Up @@ -141,7 +141,7 @@ export const getTotalListeningOfArtist = async (
) => {
// Non sense to compute blacklist here
const res = await InfosModel.aggregate([
{ $match: { owner: user._id } },
{ $match: { owner: user._id, primaryArtistId: artistId } },
...getArtistInfos(artistId),
{
$group: {
Expand All @@ -167,37 +167,7 @@ export const getMostListenedAlbumOfArtist = async (
artistId: string,
) => {
const res = await InfosModel.aggregate([
{ $match: { owner: user._id } },
{ $lookup: {
from: 'tracks',
localField: 'id',
foreignField: 'id',
as: 'track'
}},
{ $match: { 'track.artists.0': artistId } },
{ $group: {
_id: '$track.album',
count: { $sum: 1 }
}},
{ $sort: { count: -1 } },
{
$lookup: {
from: 'albums',
localField: '_id',
foreignField: 'id',
as: 'album',
},
},
{ $unwind: '$album' },
{ $limit: 10}
]);
return res;
};

export const getRankOfArtist = async (user: User, artistId: string) => {
// Non sense to compute blacklist here
const res = await InfosModel.aggregate([
{ $match: { owner: user._id } },
{ $match: { owner: user._id, primaryArtistId: artistId } },
{
$lookup: {
from: "tracks",
Expand All @@ -206,47 +176,31 @@ export const getRankOfArtist = async (user: User, artistId: string) => {
as: "track",
},
},
{ $unwind: "$track" },
{
$group: {
_id: { $arrayElemAt: ["$track.artists", 0] },
_id: "$track.album",
count: { $sum: 1 },
},
},
{ $sort: { count: -1, _id: 1 } },
{ $group: { _id: 1, array: { $push: { id: "$_id", count: "$count" } } } },
{
$project: {
index: { $indexOfArray: ["$array.id", artistId] },
array: 1,
},
},
{ $sort: { count: -1 } },
{
$project: {
index: 1,
isMax: {
$cond: { if: { $eq: ["$index", 0] }, then: true, else: false },
},
isMin: {
$cond: {
if: { $eq: ["$index", { $subtract: [{ $size: "$array" }, 1] }] },
then: true,
else: false,
},
},
results: {
$slice: ["$array", { $max: [{ $subtract: ["$index", 1] }, 0] }, 3],
},
$lookup: {
from: "albums",
localField: "_id",
foreignField: "id",
as: "album",
},
},
{ $unwind: "$album" },
{ $limit: 10 },
]);
return res[0];
return res;
};

export const getDayRepartitionOfArtist = (user: User, artistId: string) =>
// Non sense to compute blacklist here
InfosModel.aggregate([
{ $match: { owner: user._id } },
{ $match: { owner: user._id, primaryArtistId: artistId } },
{ $addFields: getGroupByDateProjection(user.settings.timezone) },
...getArtistInfos(artistId),
{
Expand Down
Loading