improve selector
This commit is contained in:
parent
f0440ed65f
commit
e0030aba73
|
@ -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) {
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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 = {
|
||||
|
|
Loading…
Reference in New Issue