Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 31 additions & 10 deletions server/graphql/types/station.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import DataLoader from 'dataloader'
import { map } from 'lodash'
import db, {aql} from '../../db'
import Route from './route'

Expand Down Expand Up @@ -27,11 +29,24 @@ export const resolvers = {
longitude ({ stop_lon }) {
return stop_lon
},
routes ({ stop_id }, {from, length}) {
return db().query(aql`
routes ({ stop_id }, { from, length }) {
return RoutesByStationIdLoader.load({ stop_id, from, length })
}
}
}

const getRoutesByStationIds = (stopIds) => {
const { from, length } = stopIds[0]
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Il faudrait que les paramètres de pagination puissent différents pour chaque id. Mais j'imagine que c'est pour commencer là. :)

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oui je sais pas trop comment les gérer pour le moment

stopIds = map(stopIds, 'stop_id')

return new Promise((resolve, reject) => {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tu peux retourner directement db().query(...).then(cursor => cursor.all())

Copy link
Copy Markdown
Owner Author

@antoinecellier antoinecellier Dec 19, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

J'avais tenté cette requête mais sans succès, il ne connait pas stopResolve.from et stopResolve.length

`

   for stopResolve in ${stops} //[{ id, from, length}, { id, from, length}, { id, from, length}]
    let stops = (
      for stop in stops
      filter stop.parent_station == stopResolve.id
      return stop.stop_id
    )

    let stop_times_of_stop = (
      for stop_time in stop_times
      filter stop_time.stop_id in stops
      return stop_time.trip_id
    )

    let routes_of_stops = (
      for trip in trips
      filter trip.trip_id in stop_times_of_stop
      return trip.route_id
    )

    let routes = (
      for route in routes
      filter route.route_id in routes_of_stops
      limit stopResolve.from, stopResolve.length
      return route
    )

  return routes

`

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tu peux regarder dans les logs de la base pour voir quelle requête arrive vraiment à la base. Je pense qu'elle ne doit pas bien contenir l'objet stops.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

J'ai loggé cette requête côté arangodb

`
for stopId in @value0
let from = stopId.from

    let stops = (
      for stop in stops
      filter stop.parent_station == stopId
      return stop.stop_id
    )

    let stop_times_of_stop = (
      for stop_time in stop_times
      filter stop_time.stop_id in stops
      return stop_time.trip_id
    )
    let routes_of_stops = (
      for trip in trips
      filter trip.trip_id in stop_times_of_stop
      return trip.route_id
    )
    let routes = (
      for route in routes
      filter route.route_id in routes_of_stops
      limit @value1, @value2
      return route
    )
  return routes

`

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Les paramètres n'apparaissent pas ?

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2017-01-17T20:20:53Z [7038] DEBUG {queries} bindParameters: {"value0":["StopArea:OTAG","StopArea:MAI8","StopArea:HMVE","StopArea:ABDU","StopArea:ADAP"],"value1":0,"value2":3}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On voit que stops/@value0 n'est pas un tableau d'objet comme tu le voudrais.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2017-01-17T20:41:12Z [8249] DEBUG {queries} bindParameters: {"value0":[{"from":0,"length":3,"stop_id":"StopArea:OTAG"},{"from":0,"length":3,"stop_id":"StopArea:MAI8"},{"from":0,"length":3,"stop_id":"StopArea:HMVE"},{"from":0,"length":3,"stop_id":"StopArea:ABDU"},{"from":0,"length":3,"stop_id":"StopArea:ADAP"}],"value1":0,"value2":3}

Petite coquille dans mon code je mappais sur stop_id. Par contre toujours pas possible de variabiliser la pagination limit stopId.from, stopId.length

^ ArangoError: syntax error, unexpected identifier near 'stopId.from, stopId.length ...' at position 26:17 (while parsing)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://docs.arangodb.com/3.1/AQL/Operations/Limit.html

Note that variables and expressions can not be used for offset and count. Their values must be known at query compile time, which means that you can use number literals and bind parameters only.

:/

db().query(aql`
for stopId in ${stopIds}
let from = stopId.from
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Qu'est-ce ?

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

un reste de fail :) L'impression que je peux pas variabiliser les valeur de LIMIT dans AQL...


let stops = (
for stop in stops
filter stop.parent_station == ${stop_id}
filter stop.parent_station == stopId
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Je crois que c'est un peu plus performant si tu fais filter stop.parent_station in ${stopIds} plutôt que le for.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alors oui mais en fait les paramètres de pagination font partie de ta clé et doivent pouvoir être différents pour chaque arrêt. Donc tu es obligé de revoir un peu ta requête et de faire un for.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Je suis obliger de wraper avec un 'for' ce qu'attend dataloader en retour est une Promise<array<value>> et l'array doit être de la même taille que le tableau passer en paramètre de const getRoutesByStationIds = (stopIds) => {

return stop.stop_id
)

Expand All @@ -47,15 +62,21 @@ export const resolvers = {
return trip.route_id
)

for route in routes
filter route.route_id in routes_of_stops
limit ${from}, ${length}
return route
`).then(cursor => cursor.all())
}
}
let routes = (
for route in routes
filter route.route_id in routes_of_stops
limit ${from}, ${length}
return route
)

return routes
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Je ne suis pas sûr que cette requête marche pour plus d'un arrêt, parce que la variable routes est écrasée.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

La requête semble fonctionner comme il faut pourtant

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oui en fait AQL n'a que faire de l'indentation. Le for va jusqu'au return donc c'est OK.

`).then(cursor => cursor.all())
.then(routes => resolve(routes))
});
}

const RoutesByStationIdLoader = new DataLoader(getRoutesByStationIds);

export function stationDbId (stationDtoId) {
return 'StopArea:' + stationDtoId
}
4 changes: 2 additions & 2 deletions server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@
"co": "^4.6.0",
"co-express": "^1.2.2",
"cors": "^2.8.1",
"dataloader": "^1.2.0",
"express": "git+https://github.com/expressjs/express.git#1dbfee66235c6a4e2f8e440264f71f31ddbe75d4",
"express-graphql": "^0.5.4",
"falcor-express": "^0.1.2",
"falcor-router": "^0.4.0",
"express-graphql": "^0.5.4",
"graphql": "^0.7.0",
"cors": "^2.8.1",
"http2": "^3.3.4",
"joi": "^9.0.4",
"lodash.flatten": "^4.4.0",
Expand Down