improve selector

This commit is contained in:
sbriat 2023-09-04 17:29:16 +02:00
parent f0440ed65f
commit e0030aba73
3 changed files with 79 additions and 21 deletions

View File

@ -7,6 +7,7 @@ import { Inject } from '@nestjs/common';
import { AdRepositoryPort } from '@modules/ad/core/application/ports/ad.repository.port';
import {
AD_REPOSITORY,
AD_ROUTE_PROVIDER,
INPUT_DATETIME_TRANSFORMER,
PARAMS_PROVIDER,
} from '@modules/ad/ad.di-tokens';
@ -14,6 +15,7 @@ import { MatchEntity } from '@modules/ad/core/domain/match.entity';
import { DefaultParamsProviderPort } from '../../ports/default-params-provider.port';
import { DefaultParams } from '../../ports/default-params.type';
import { DateTimeTransformerPort } from '../../ports/datetime-transformer.port';
import { RouteProviderPort } from '../../ports/route-provider.port';
@QueryHandler(MatchQuery)
export class MatchQueryHandler implements IQueryHandler {
@ -25,6 +27,8 @@ export class MatchQueryHandler implements IQueryHandler {
@Inject(AD_REPOSITORY) private readonly repository: AdRepositoryPort,
@Inject(INPUT_DATETIME_TRANSFORMER)
private readonly datetimeTransformer: DateTimeTransformerPort,
@Inject(AD_ROUTE_PROVIDER)
private readonly routeProvider: RouteProviderPort,
) {
this._defaultParams = defaultParamsProvider.getParams();
}
@ -50,6 +54,7 @@ export class MatchQueryHandler implements IQueryHandler {
maxDetourDurationRatio: this._defaultParams.MAX_DETOUR_DURATION_RATIO,
})
.setDatesAndSchedule(this.datetimeTransformer);
await query.setRoutes(this.routeProvider);
let algorithm: Algorithm;
switch (query.algorithmType) {

View File

@ -1,9 +1,11 @@
import { QueryBase } from '@mobicoop/ddd-library';
import { AlgorithmType } from '../../types/algorithm.types';
import { Waypoint } from '../../types/waypoint.type';
import { Frequency } from '@modules/ad/core/domain/ad.types';
import { Frequency, Role } from '@modules/ad/core/domain/ad.types';
import { MatchRequestDto } from '@modules/ad/interface/grpc-controllers/dtos/match.request.dto';
import { DateTimeTransformerPort } from '../../ports/datetime-transformer.port';
import { Route } from '../../types/route.type';
import { RouteProviderPort } from '../../ports/route-provider.port';
export class MatchQuery extends QueryBase {
driver?: boolean;
@ -26,6 +28,7 @@ export class MatchQuery extends QueryBase {
maxDetourDurationRatio?: number;
readonly page?: number;
readonly perPage?: number;
route?: Route;
constructor(props: MatchRequestDto) {
super();
@ -160,6 +163,18 @@ export class MatchQuery extends QueryBase {
}));
return this;
};
setRoutes = async (routeProvider: RouteProviderPort): Promise<MatchQuery> => {
const roles: Role[] = [];
if (this.driver) roles.push(Role.DRIVER);
if (this.passenger) roles.push(Role.PASSENGER);
try {
this.route = await routeProvider.getBasic(roles, this.waypoints);
} catch (e: any) {
throw new Error('Unable to find a route for given waypoints');
}
return this;
};
}
type ScheduleItem = {

View File

@ -1,4 +1,4 @@
import { Role } from '@modules/ad/core/domain/ad.types';
import { Frequency, Role } from '@modules/ad/core/domain/ad.types';
import { Candidate } from '../../../types/algorithm.types';
import { Selector } from '../algorithm.abstract';
import { AdReadModel } from '@modules/ad/infrastructure/ad.repository';
@ -8,15 +8,16 @@ export class PassengerOrientedSelector extends Selector {
const queryStringRoles: QueryStringRole[] = [];
if (this.query.driver)
queryStringRoles.push({
query: this.asDriverQueryString(),
query: this.createQueryString(Role.DRIVER),
role: Role.DRIVER,
});
if (this.query.passenger)
queryStringRoles.push({
query: this.asPassengerQueryString(),
query: this.createQueryString(Role.PASSENGER),
role: Role.PASSENGER,
});
console.log(queryStringRoles);
return (
await Promise.all(
queryStringRoles.map<Promise<AdsRole>>(
@ -42,29 +43,66 @@ export class PassengerOrientedSelector extends Selector {
.flat();
};
private asPassengerQueryString = (): string => `SELECT
ad.uuid,driver,passenger,frequency,public.st_astext(matcher.ad.waypoints) as waypoints,
"fromDate","toDate",
"seatsProposed","seatsRequested",
strict,
"driverDuration","driverDistance",
"passengerDuration","passengerDistance",
"fwdAzimuth","backAzimuth",
si.day,si.time,si.margin
FROM ad LEFT JOIN schedule_item si ON ad.uuid = si."adUuid"
WHERE driver=True`;
private createQueryString = (role: Role): string =>
[
this.createSelect(role),
this.createFrom(),
'WHERE',
this.createWhere(role),
].join(' ');
private asDriverQueryString = (): string => `SELECT
private createSelect = (role: Role): string =>
[
`SELECT
ad.uuid,driver,passenger,frequency,public.st_astext(matcher.ad.waypoints) as waypoints,
"fromDate","toDate",
"seatsProposed","seatsRequested",
strict,
"driverDuration","driverDistance",
"passengerDuration","passengerDistance",
"fwdAzimuth","backAzimuth",
si.day,si.time,si.margin
FROM ad LEFT JOIN schedule_item si ON ad.uuid = si."adUuid"
WHERE passenger=True`;
si.day,si.time,si.margin`,
role == Role.DRIVER ? this.selectAsDriver() : this.selectAsPassenger(),
].join();
private selectAsDriver = (): string =>
`${this.query.route?.driverDuration} as duration,${this.query.route?.driverDistance} as distance`;
private selectAsPassenger = (): string =>
`"driverDuration" as duration,"driverDistance" as distance`;
private createFrom = (): string =>
'FROM ad LEFT JOIN schedule_item si ON ad.uuid = si."adUuid"';
private createWhere = (role: Role): string =>
[this.whereRole(role), this.whereStrict(), this.whereDate()].join(' AND ');
private whereRole = (role: Role): string =>
role == Role.PASSENGER ? 'driver=True' : 'passenger=True';
private whereStrict = (): string =>
this.query.strict
? this.query.frequency == Frequency.PUNCTUAL
? `frequency='${Frequency.PUNCTUAL}'`
: `frequency='${Frequency.RECURRENT}'`
: '';
private whereDate = (): string => {
const whereDate = `(
(
"fromDate" <= '${this.query.fromDate}' and "fromDate" <= '${this.query.toDate}' and
"toDate" >= '${this.query.toDate}' and "toDate" >= '${this.query.fromDate}'
) OR (
"fromDate" >= '${this.query.fromDate}' and "fromDate" <= '${this.query.toDate}' and
"toDate" <= '${this.query.toDate}' and "toDate" >= '${this.query.fromDate}'
) OR (
"fromDate" <= '${this.query.fromDate}' and "fromDate" <= '${this.query.toDate}' and
"toDate" <= '${this.query.toDate}' and "toDate" >= '${this.query.fromDate}'
) OR (
"fromDate" >= '${this.query.fromDate}' and "fromDate" <= '${this.query.toDate}' and
"toDate" >= '${this.query.toDate}' and "toDate" >= '${this.query.fromDate}'
)
)`;
return whereDate;
};
}
export type QueryStringRole = {