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 { AdRepositoryPort } from '@modules/ad/core/application/ports/ad.repository.port';
|
||||||
import {
|
import {
|
||||||
AD_REPOSITORY,
|
AD_REPOSITORY,
|
||||||
|
AD_ROUTE_PROVIDER,
|
||||||
INPUT_DATETIME_TRANSFORMER,
|
INPUT_DATETIME_TRANSFORMER,
|
||||||
PARAMS_PROVIDER,
|
PARAMS_PROVIDER,
|
||||||
} from '@modules/ad/ad.di-tokens';
|
} 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 { DefaultParamsProviderPort } from '../../ports/default-params-provider.port';
|
||||||
import { DefaultParams } from '../../ports/default-params.type';
|
import { DefaultParams } from '../../ports/default-params.type';
|
||||||
import { DateTimeTransformerPort } from '../../ports/datetime-transformer.port';
|
import { DateTimeTransformerPort } from '../../ports/datetime-transformer.port';
|
||||||
|
import { RouteProviderPort } from '../../ports/route-provider.port';
|
||||||
|
|
||||||
@QueryHandler(MatchQuery)
|
@QueryHandler(MatchQuery)
|
||||||
export class MatchQueryHandler implements IQueryHandler {
|
export class MatchQueryHandler implements IQueryHandler {
|
||||||
|
@ -25,6 +27,8 @@ export class MatchQueryHandler implements IQueryHandler {
|
||||||
@Inject(AD_REPOSITORY) private readonly repository: AdRepositoryPort,
|
@Inject(AD_REPOSITORY) private readonly repository: AdRepositoryPort,
|
||||||
@Inject(INPUT_DATETIME_TRANSFORMER)
|
@Inject(INPUT_DATETIME_TRANSFORMER)
|
||||||
private readonly datetimeTransformer: DateTimeTransformerPort,
|
private readonly datetimeTransformer: DateTimeTransformerPort,
|
||||||
|
@Inject(AD_ROUTE_PROVIDER)
|
||||||
|
private readonly routeProvider: RouteProviderPort,
|
||||||
) {
|
) {
|
||||||
this._defaultParams = defaultParamsProvider.getParams();
|
this._defaultParams = defaultParamsProvider.getParams();
|
||||||
}
|
}
|
||||||
|
@ -50,6 +54,7 @@ export class MatchQueryHandler implements IQueryHandler {
|
||||||
maxDetourDurationRatio: this._defaultParams.MAX_DETOUR_DURATION_RATIO,
|
maxDetourDurationRatio: this._defaultParams.MAX_DETOUR_DURATION_RATIO,
|
||||||
})
|
})
|
||||||
.setDatesAndSchedule(this.datetimeTransformer);
|
.setDatesAndSchedule(this.datetimeTransformer);
|
||||||
|
await query.setRoutes(this.routeProvider);
|
||||||
|
|
||||||
let algorithm: Algorithm;
|
let algorithm: Algorithm;
|
||||||
switch (query.algorithmType) {
|
switch (query.algorithmType) {
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
import { QueryBase } from '@mobicoop/ddd-library';
|
import { QueryBase } from '@mobicoop/ddd-library';
|
||||||
import { AlgorithmType } from '../../types/algorithm.types';
|
import { AlgorithmType } from '../../types/algorithm.types';
|
||||||
import { Waypoint } from '../../types/waypoint.type';
|
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 { MatchRequestDto } from '@modules/ad/interface/grpc-controllers/dtos/match.request.dto';
|
||||||
import { DateTimeTransformerPort } from '../../ports/datetime-transformer.port';
|
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 {
|
export class MatchQuery extends QueryBase {
|
||||||
driver?: boolean;
|
driver?: boolean;
|
||||||
|
@ -26,6 +28,7 @@ export class MatchQuery extends QueryBase {
|
||||||
maxDetourDurationRatio?: number;
|
maxDetourDurationRatio?: number;
|
||||||
readonly page?: number;
|
readonly page?: number;
|
||||||
readonly perPage?: number;
|
readonly perPage?: number;
|
||||||
|
route?: Route;
|
||||||
|
|
||||||
constructor(props: MatchRequestDto) {
|
constructor(props: MatchRequestDto) {
|
||||||
super();
|
super();
|
||||||
|
@ -160,6 +163,18 @@ export class MatchQuery extends QueryBase {
|
||||||
}));
|
}));
|
||||||
return this;
|
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 = {
|
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 { Candidate } from '../../../types/algorithm.types';
|
||||||
import { Selector } from '../algorithm.abstract';
|
import { Selector } from '../algorithm.abstract';
|
||||||
import { AdReadModel } from '@modules/ad/infrastructure/ad.repository';
|
import { AdReadModel } from '@modules/ad/infrastructure/ad.repository';
|
||||||
|
@ -8,15 +8,16 @@ export class PassengerOrientedSelector extends Selector {
|
||||||
const queryStringRoles: QueryStringRole[] = [];
|
const queryStringRoles: QueryStringRole[] = [];
|
||||||
if (this.query.driver)
|
if (this.query.driver)
|
||||||
queryStringRoles.push({
|
queryStringRoles.push({
|
||||||
query: this.asDriverQueryString(),
|
query: this.createQueryString(Role.DRIVER),
|
||||||
role: Role.DRIVER,
|
role: Role.DRIVER,
|
||||||
});
|
});
|
||||||
if (this.query.passenger)
|
if (this.query.passenger)
|
||||||
queryStringRoles.push({
|
queryStringRoles.push({
|
||||||
query: this.asPassengerQueryString(),
|
query: this.createQueryString(Role.PASSENGER),
|
||||||
role: Role.PASSENGER,
|
role: Role.PASSENGER,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
console.log(queryStringRoles);
|
||||||
return (
|
return (
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
queryStringRoles.map<Promise<AdsRole>>(
|
queryStringRoles.map<Promise<AdsRole>>(
|
||||||
|
@ -42,29 +43,66 @@ export class PassengerOrientedSelector extends Selector {
|
||||||
.flat();
|
.flat();
|
||||||
};
|
};
|
||||||
|
|
||||||
private asPassengerQueryString = (): string => `SELECT
|
private createQueryString = (role: Role): string =>
|
||||||
ad.uuid,driver,passenger,frequency,public.st_astext(matcher.ad.waypoints) as waypoints,
|
[
|
||||||
"fromDate","toDate",
|
this.createSelect(role),
|
||||||
"seatsProposed","seatsRequested",
|
this.createFrom(),
|
||||||
strict,
|
'WHERE',
|
||||||
"driverDuration","driverDistance",
|
this.createWhere(role),
|
||||||
"passengerDuration","passengerDistance",
|
].join(' ');
|
||||||
"fwdAzimuth","backAzimuth",
|
|
||||||
si.day,si.time,si.margin
|
|
||||||
FROM ad LEFT JOIN schedule_item si ON ad.uuid = si."adUuid"
|
|
||||||
WHERE driver=True`;
|
|
||||||
|
|
||||||
private asDriverQueryString = (): string => `SELECT
|
private createSelect = (role: Role): string =>
|
||||||
|
[
|
||||||
|
`SELECT
|
||||||
ad.uuid,driver,passenger,frequency,public.st_astext(matcher.ad.waypoints) as waypoints,
|
ad.uuid,driver,passenger,frequency,public.st_astext(matcher.ad.waypoints) as waypoints,
|
||||||
"fromDate","toDate",
|
"fromDate","toDate",
|
||||||
"seatsProposed","seatsRequested",
|
"seatsProposed","seatsRequested",
|
||||||
strict,
|
strict,
|
||||||
"driverDuration","driverDistance",
|
|
||||||
"passengerDuration","passengerDistance",
|
|
||||||
"fwdAzimuth","backAzimuth",
|
"fwdAzimuth","backAzimuth",
|
||||||
si.day,si.time,si.margin
|
si.day,si.time,si.margin`,
|
||||||
FROM ad LEFT JOIN schedule_item si ON ad.uuid = si."adUuid"
|
role == Role.DRIVER ? this.selectAsDriver() : this.selectAsPassenger(),
|
||||||
WHERE passenger=True`;
|
].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 = {
|
export type QueryStringRole = {
|
||||||
|
|
Loading…
Reference in New Issue