Groupe
Les différents groupes
Il existe 6 types de groupes :
- 'ProfileGroup' : Groupes de profil
- 'FunctionalGroup' : Groupes fonctionnels.
- 'ManualGroup': Groupes gérés manuellement
- 'FunctionGroup' : Groupes par fonction, par discipline
- 'BroadcastGroup' : Liste de diffusion
- 'Classes'
Groupes de profils (ProfileGroup)
Les utilisateurs sont dans un groupes de profils (ProfileGroup).
Chaque groupe est associé à une classe (relation DEPENDS).
Chaque classe est associée à une structure (relation BELONGS).
Chaque groupe a un profil (Teacher, Personnel, Student, Relation) (relation HAS_PROFILE).
Création des profils
// Création du profil Teacher
CREATE (p:Profile {externalId: "PROFILE_TEACHER", name: "Teacher"});
// Création du profil Personnel
CREATE (p:Profile {externalId: "PROFILE_PERSONNEL", name: "Personnel"});
// Création du profil Student
CREATE (p:Profile {externalId: "PROFILE_STUDENT", name: "Student"});
// Création du profil Relative
CREATE (p:Profile {externalId: "PROFILE_RELATIVE", name: "Relative"});
Création des profils group
// Création du profil Teacher
CREATE (p:ProfileGroup {id: "PROFILE_TEACHER", externalId: "PROFILE_TEACHER", name: "Teacher"});
// Création du profil Personnel
CREATE (p:ProfileGroup {id: "PROFILE_PERSONNEL", externalId: "PROFILE_PERSONNEL", name: "Personnel"});
// Création du profil Student
CREATE (p:ProfileGroup {id: "PROFILE_STUDENT", externalId: "PROFILE_STUDENT", name: "Student"});
// Création du profil Relative
CREATE (p:ProfileGroup {id: "PROFILE_RELATIVE", externalId: "PROFILE_RELATIVE", name: "Relative"});
Création des relations
Création de la relation HAS_PROFILE entre ProfileGroup et Profile
// Créer une relation HAS_PROFILE entre ProfileGroup et Profile
:params {
structureId: 'b3380c81-e5c7-49fa-9058-a5afce4cd1ea',
profileName: 'Teacher',
profileGroupName: 'Teacher Group'
}
MATCH (pg:ProfileGroup { name: $profileGroupName })
MERGE (p:Profile { name: $profileName })
CREATE (pg)-[:HAS_PROFILE]->(p)
Création de la relation DEPENDS entre ProfileGroup et Structure
// Creer une relation DEPENDS entre ProfileGroup et Structure
MATCH (s:Structure { id: $structureId })
MATCH (pg:ProfileGroup { name: $profileGroupName })
CREATE (pg)-[:DEPENDS]->(s)
Suppression des relations
// Supprimer une relation DEPENDS entre une structure et un ProfileGroup
MATCH (a:ProfileGroup { name: $profileGroupName })-[r:DEPENDS]->(b:Structure { id: $structureId })
DELETE r;
// Supprimer une relation HAS_PROFILE entre un ProfileGroup et un Profile
MATCH (pg:ProfileGroup { name: $profileGroupName })-[r:HAS_PROFILE]->(p:Profile { name: $profileName })
RETURN r;
Groupes fonctionnels (FunctionalGroup)
On retrouve ici les groupes tels que :
- la direction (
Direction
), - le personnel administratif (
SCOLARITE
) - les professeurs principaux (
HeadTeacher
)
Exemple de groupe de Direction :
Groupes par fonction (FunctionGroup)
Un des groupes par fonction principal est le groupe permettant de gérer les administrateurs de l'établissement.
(groupe AdminLocal
)
Exemple de groupe par discipline (DisciplineGroup):
Information détaillée sur les groupes
Cette requête sert à obtenir des informations détaillées sur les groupes, y compris leurs relations avec les structures et les classes, les labels, et des propriétés spécifiques comme les règles de communication ou le nombre d'utilisateurs. Le résultat final est enrichi en catégorisant le groupe (subType) et en collectant les structures et classes associées.
MATCH (s:Structure)<-[:BELONGS*0..1]-()<-[:DEPENDS]-(g:Group)
OPTIONAL MATCH (g)-[:DEPENDS]->(c:Class)
WITH g,
collect({name: c.name, id: c.id}) as classes,
collect(distinct {name: s.name, id: s.id}) as structures,
[x IN labels(g) WHERE x <> 'Visible' AND x <> 'Group'] AS filteredLabels,
head([x IN labels(g) WHERE x <> 'Visible' AND x <> 'Group']) as type
RETURN DISTINCT g.id as id,
g.name as name,
g.displayName as displayName,
g.filter as filter,
labels(g) as labels,
g.autolinkTargetAllStructs as autolinkTargetAllStructs,
g.autolinkTargetStructs as autolinkTargetStructs,
g.autolinkUsersFromGroups as autolinkUsersFromGroups,
type,
g.users as internalCommunicationRule,
g.lockDelete AS lockDelete,
coalesce(g.nbUsers, 0) as nbUsers,
CASE WHEN any(x IN classes WHERE x.name IS NOT NULL AND x.id IS NOT NULL) THEN classes END as classes,
CASE WHEN any(x IN structures WHERE x.name IS NOT NULL AND x.id IS NOT NULL) THEN structures END as structures,
CASE
WHEN (g:ProfileGroup)-[:DEPENDS]-(:Structure) THEN 'StructureGroup'
WHEN (g:ProfileGroup)-[:DEPENDS]->(:Class) THEN 'ClassGroup'
WHEN EXISTS(g.subType) THEN g.subType
WHEN (g:ManualGroup) AND (
g.autolinkTargetAllStructs = true OR
size(coalesce(g.autolinkUsersFromGroups, [])) > 0 OR
size(coalesce(g.autolinkTargetStructs, [])) > 0
) THEN 'BroadcastGroup'
END as subType;
Utilisateur dans un groupe
MATCH (g:Group)
WHERE g.id = 68171
MATCH (u:User)-[:IN]->(g)
RETURN u
Ajouter des utilisateurs à un groupe
MATCH (u:User { id: $userId }), (f:Group { id: $groupId })
WHERE 'ManualGroup' IN labels(f) OR 'FunctionalGroup' IN labels(f)
MERGE (u)-[:IN { source: 'MANUAL' }]->(f)
WITH f, u
WHERE 'FunctionalGroup' IN labels(f)
SET u.groups = [gId IN coalesce(u.groups, []) WHERE gId <> f.externalId] + f.externalId
Cette requête Cypher a pour but d'ajouter un utilisateur (User
) à un groupe (Group
) sous certaines conditions, tout en maintenant une liste des groupes auxquels il appartient.
Explication détaillée de la requête
MATCH (u:User { id: $userId }), (f:Group { id: $groupId })
- Recherche un utilisateur (
User
) et un groupe (Group
) en fonction de leurs identifiants respectifs ($userId
et$groupId
).
WHERE 'ManualGroup' IN labels(f) OR 'FunctionalGroup' IN labels(f)
- Filtre uniquement certains types de groupes :
- Soit un
ManualGroup
- Soit un
FunctionalGroup
- Soit un
MERGE (u)-[:IN { source: 'MANUAL' }]->(f)
- Crée (ou assure l'existence) d'une relation
IN
entre l'utilisateuru
et le groupef
. - La relation a un attribut
source: 'MANUAL'
, indiquant que l'ajout est fait manuellement.
WITH f, u
WHERE 'FunctionalGroup' IN labels(f)
- Continue uniquement si
f
est unFunctionalGroup
. - Cela signifie que la mise à jour des groupes ne se fait que pour ce type de groupe.
SET u.groups = [gId IN coalesce(u.groups, []) WHERE gId <> f.externalId] + f.externalId
- Met à jour la propriété
groups
de l'utilisateuru
en :- Filtrant les anciens groupes (
u.groups
) pour supprimer l'ID externe (externalId
) def
s'il est déjà présent. - Ajoutant
f.externalId
à la liste des groupes.
- Filtrant les anciens groupes (
Objectif fonctionnel
- Cette requête ajoute un utilisateur à un groupe, mais ne duplique pas l'ajout s'il est déjà dans le groupe.
- Elle maintient une liste
groups
sur l'utilisateur, qui stocke lesexternalId
des groupes de typeFunctionalGroup
uniquement.
Exemple concret
Données initiales
CREATE (:User { id: "123", groups: ["G1", "G2"] })
CREATE (:Group { id: "456", externalId: "G3", labels: ["FunctionalGroup"] })
Exécution de la requête avec
$userId = "123"
$groupId = "456"
Résultat attendu
- La relation
(:User)-[:IN]->(:Group)
est créée. - La liste
u.groups
est mise à jour de :à["G1", "G2"]
(sans doublon et en supprimant["G1", "G2", "G3"]
G3
s'il était déjà présent).
Récupération des informations d'un groupe
MATCH (g:ProfileGroup|FunctionGroup {id: 68171})
OPTIONAL MATCH (g)-[:DEPENDS]->(s:Structure)
OPTIONAL MATCH (g)-[:DEPENDS]->(c:Class)
OPTIONAL MATCH (g)<-[:IN]-(u:User)
RETURN
g.id AS groupId,
g.name AS groupName,
g.filter AS groupType,
labels(g) AS groupLabels,
s.id AS structureId,
s.name AS structureName,
c.id AS classId,
c.name AS className,
count(u) AS memberCount
Ajouter manuellement un groupe à un utilisateur
MATCH (u:User { id: $userId }), (f:Group { id: $groupId })
WHERE 'ManualGroup' IN labels(f) OR 'FunctionalGroup' IN labels(f)
MERGE (u)-[:IN { source: 'MANUAL' }]->(f)
WITH f, u
WHERE 'FunctionalGroup' IN labels(f)
SET u.groups = [gId IN coalesce(u.groups, []) WHERE gId <> f.externalId] + f.externalId