anchor.diff:  WITH me, colleagues
   WHERE (me-[:IN_CONTACT_WITH]-(:CONTACT)-[:IN_CONTACT_WITH]-colleagues)
   RETURN me, colleagues
  -----------------------------------------------------------------------
  +----
   
   Sympa, non ?
   
  -Allez, une dernière pour la route : pour que de retourner n associations
  -1-1 comme c’est le cas actuellement, les autorités compétentes m’ont
  -demandé de directement retourner une association 1-n avec les collègues
  -triés par nom. Autrement dit : retourner la collection agrégée de
  -collègues.
  -
  -Petite subtilité : rien ne vous garantit l’ordre des collègues qui vous
  -a été retourné. Nous pouvons utiliser la clause ORDER BY juste après
  -WITH, afin de s’assurer que les collègues sont triés (l’opération de
  -filtrage qui suit n’y changera rien).
  -
  -----------------------------------------------------------------------
  +Allez, une dernière pour la route : pour que de retourner n associations 1-1 comme c’est le cas actuellement, les autorités compétentes m’ont demandé de directement retourner une association 1-n avec les collègues triés par nom. Autrement dit : retourner la collection agrégée de collègues.
  +
  +Petite subtilité : rien ne vous garantit l’ordre des collègues qui vous a été retourné. Nous pouvons utiliser la clause ORDER BY juste après WITH, afin de s’assurer que les collègues sont triés (l’opération de filtrage qui suit n’y changera rien).
  +
  +[source,cypher]
  +----
   MATCH (me:CONTACT)-[myStay:WORKED_IN]->(company:COMPANY),
   company<-[theirStay:WORKED_IN]-(colleagues:CONTACT)
   WHERE me.name = {name} AND NOT (me-[:IN_CONTACT_WITH]-colleagues)
  
positive.code: WITH me, colleagues
  ORDER BY colleagues.name
  WHERE (me-[:IN_CONTACT_WITH]-(:CONTACT)-[:IN_CONTACT_WITH]-colleagues)
  RETURN me, COLLECT(colleagues)
  ----------------------------------------------------------------------
  
  Et le tour est joué !
  
  Les avantages d’avoir découpé la requête comme suit sont multiples :
  
  * la requête, découpée en blocs distincts, est nettement plus lisible
  * elle est également plus maintenable puisque chaque bloc se voit
  confier une partie bien identifiée du problème à résoudre
  * et surtout, puisque l’on retourne toujours le contact concerné et ses
  suggestions de contact, je peux me permettre d’opérer à la “fire and
  forget” puisque le résultat de la requête contient tout le contexte
  nécessaire à son interprétation
  
  Le mot de la fin
  ~~~~~~~~~~~~~~~~
  
negative.code: d’ailleurs, pour séparer le MATCH en deux sous-patterns, afin
  d’améliorer la lisibilité de la requête.
  
  [source,cypher]
  ----
  MATCH (me:CONTACT)-[myStay:WORKED_IN]->(company:COMPANY),
  company<-[theirStay:WORKED_IN]-(colleagues:CONTACT)
  WHERE me.name = {name} AND NOT (me-[:IN_CONTACT_WITH]-colleagues)
  RETURN me, colleagues
  ----
  
  Exprimons maintenant les contraintes de chevauchement :
  
  [source,cypher]
  ----
  MATCH (me:CONTACT)-[myStay:WORKED_IN]->(company:COMPANY),
  company<-[theirStay:WORKED_IN]-(colleagues:CONTACT)
  WHERE me.name = {name} AND NOT (me-[:IN_CONTACT_WITH]-colleagues)
  AND myStay.beginning < theirStay.end
  AND theirStay.beginning < myStay.end
  RETURN me, colleagues
  ----
  
  … sans oublier le fait que les personnes peuvent encore être présentes
  dans l’entreprise (auquel cas la propriété end ne sera tout simplement
  pas renseignée).
  
  
  [source,cypher]
  ----
  MATCH (me:CONTACT)-[myStay:WORKED_IN]->(company:COMPANY),
  company<-[theirStay:WORKED_IN]-(colleagues:CONTACT)
  WHERE me.name = {name} AND NOT (me-[:IN_CONTACT_WITH]-colleagues)
  AND (NOT HAS(theirStay.end) OR myStay.beginning < theirStay.end)
  AND (NOT HAS(myStay.end) OR theirStay.beginning < myStay.end)
  RETURN me, colleagues
  ----
  
  Filtrage des collègues par contact
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  