Utiliser des mesures
Ce document explique comment définir et interroger des mesures sur vos graphiques. Vous pouvez utiliser des mesures pour vous assurer que les agrégations sont effectuées correctement sur les jointures.
Présentation
Une mesure est une propriété agrégée définie dans la clause PROPERTIES d'une table de nœuds ou d'arêtes. Les mesures sont définies à l'aide du mot clé MEASURE et de l'une des fonctions d'agrégation compatibles suivantes :
SUMAVGCOUNTCOUNT(DISTINCT)MINMAX
Les mesures définissent leur agrégation en référence à la KEY de la table de nœuds ou d'arêtes sur laquelle elles sont définies. Cela signifie que lorsque vous interrogez une mesure, l'agrégation est effectuée correctement, même si la table sous-jacente est jointe de manière à entraîner la duplication des lignes.
Vous ne pouvez pas faire référence à une propriété définie par une mesure dans une requête GQL. Au lieu de cela,
vous accédez aux mesures en appelant la
GRAPH_EXPAND TVF
pour créer une représentation de table aplatie de votre graphique. Cette fonction n'accepte pas tous les types de graphiques. Pour en savoir plus sur
les graphiques qui constituent une entrée valide, consultez les limites d'entrée.
Vous pouvez appeler la
AGG fonction
sur la sortie de la GRAPH_EXPAND TVF pour agréger
les propriétés en fonction de la fonction d'agrégation que vous avez définie dans
la mesure.
Définir des mesures
Vous définissez des mesures dans la
PROPERTIES clause
d'une définition de table de nœuds ou d'arêtes à l'aide du MEASURE() mot clé autour d'une
fonction d'agrégation compatible.
L'exemple suivant crée un ensemble de données appelé university et des tables pour les facultés, les départements et les cours :
CREATE SCHEMA IF NOT EXISTS university;
CREATE OR REPLACE TABLE university.College (
college_id INT64 PRIMARY KEY NOT ENFORCED,
college_name STRING
);
CREATE OR REPLACE TABLE university.Department (
dept_id INT64 PRIMARY KEY NOT ENFORCED,
dept_name STRING,
college_id INT64,
budget FLOAT64,
FOREIGN KEY (college_id) REFERENCES university.College(college_id) NOT ENFORCED
);
CREATE OR REPLACE TABLE university.Course (
course_id INT64 PRIMARY KEY NOT ENFORCED,
course_name STRING,
dept_id INT64,
credits INT64,
FOREIGN KEY (dept_id) REFERENCES university.Department(dept_id) NOT ENFORCED
);
INSERT INTO university.College (college_id, college_name)
VALUES (101, 'College of Engineering'),
(102, 'College of Arts');
INSERT INTO university.Department (dept_id, dept_name, college_id, budget)
VALUES (1001, 'Computer Science', 101, 500000),
(1002, 'Mechanical Engineering', 101, 400000),
(1003, 'Fine Arts', 102, 200000),
(1004, 'Research', 101, 50000);
INSERT INTO university.Course (course_id, course_name, dept_id, credits)
VALUES (1, 'Intro to CS', 1001, 3),
(2, 'Data Structures', 1001, 4),
(3, 'Thermodynamics', 1002, 3),
(4, 'Oil Painting', 1003, 2);
L'instruction suivante crée un graphique appelé SchoolGraph qui définit des mesures sur certaines propriétés des nœuds Department et Course.
Vous devez fournir un alias pour les propriétés définies par une mesure.
CREATE OR REPLACE PROPERTY GRAPH university.SchoolGraph
NODE TABLES (
university.College
KEY(college_id)
PROPERTIES(college_id, college_name),
university.Department
KEY(dept_id)
PROPERTIES(dept_id, dept_name, college_id,
budget OPTIONS(description="Department budget in USD"),
MEASURE(SUM(budget)) AS total_budget),
university.Course
KEY(course_id)
PROPERTIES(
course_id,
course_name,
credits,
dept_id,
MEASURE(AVG(credits)) AS avg_credits,
MEASURE(SUM(credits)) AS total_credits,
MEASURE(COUNT(course_id)) AS course_count)
)
EDGE TABLES (
university.Department AS CollegeDept
SOURCE KEY (college_id) REFERENCES College (college_id)
DESTINATION KEY (dept_id) REFERENCES Department (dept_id),
university.Course AS DeptCourse
SOURCE KEY (dept_id) REFERENCES Department (dept_id)
DESTINATION KEY (course_id) REFERENCES Course (course_id)
);

La mesure total_budget est définie comme MEASURE(SUM(budget)). La mesure verrouille l'agrégation sur la KEY, qui est dept_id.
Comprendre le surcomptage
Lorsque vous joignez des tables, les données sont répétées chaque fois qu'il existe une relation un-à-plusieurs dans vos données. Par exemple, si vous joignez les tables Course, Department et College, un département comportant plusieurs cours apparaît dans plusieurs lignes de la sortie :
SELECT
college_name,
dept_name,
course_name,
budget
FROM university.Course
LEFT JOIN university.Department
ON Course.dept_id = Department.dept_id
LEFT JOIN university.College
ON Department.college_id = College.college_id;
/*------------------------+------------------------+-----------------+----------+
| college_name | dept_name | course_name | budget |
+------------------------+------------------------+-----------------+----------+
| College of Engineering | Computer Science | Intro to CS | 500000.0 |
| College of Engineering | Computer Science | Data Structures | 500000.0 |
| College of Engineering | Mechanical Engineering | Thermodynamics | 400000.0 |
| College of Arts | Fine Arts | Oil Painting | 200000.0 |
+------------------------+------------------------+-----------------+----------*/
Si vous essayez de calculer le budget total par faculté à l'aide de SUM(budget), le budget du département d'informatique est comptabilisé deux fois. Vous pouvez éviter ce problème en interrogeant directement la table Department, mais cette approche ne fonctionne pas si vous souhaitez calculer plusieurs agrégations à partir de différentes tables qui contribuent à vos données jointes. La section suivante explique comment les mesures résolvent ce problème.
Interroger un graphique avec des mesures
Vous pouvez interroger un graphique avec des mesures à l'aide de GQL, mais votre requête ne peut pas faire référence directement à une propriété définie par une mesure. Par exemple, la requête suivante fait référence à des nœuds pour lesquels des propriétés de mesure sont définies, mais n'utilise ni ne renvoie aucun des champs de mesure :
GRAPH university.SchoolGraph
MATCH (c:College)-[]-(d:Department)-[]->(course:Course)
RETURN c.college_name, d.dept_name, course.course_name;
/*------------------------+------------------------+-----------------+
| college_name | dept_name | course_name |
+------------------------+------------------------+-----------------+
| College of Engineering | Computer Science | Intro to CS |
| College of Engineering | Computer Science | Data Structures |
| College of Engineering | Mechanical Engineering | Thermodynamics |
| College of Arts | Fine Arts | Oil Painting |
+------------------------+------------------------+-----------------*/
Utiliser des mesures
Pour utiliser des mesures, vous utilisez la
GRAPH_EXPAND
fonction de valeur de table (TVF)
afin d'interroger votre graphique sous la forme d'une seule table aplatie.
Les colonnes de la table de sortie sont dérivées des propriétés définies dans le graphe pour chaque table de nœuds et d'arêtes. Pour éviter les conflits de noms, les colonnes sont nommées en concaténant le libellé de la table de nœuds ou d'arêtes et le nom de la propriété, par exemple Course_course_name ou Department_total_budget. La requête suivante montre un exemple de résultat de la TVF GRAPH_EXPAND :
SELECT
College_college_name,
Department_dept_name,
Department_budget,
Course_course_name
FROM
GRAPH_EXPAND("university.SchoolGraph");
/*------------------------+------------------------+-------------------+--------------------+
| College_college_name | Department_dept_name | Department_budget | Course_course_name |
+------------------------+------------------------+-------------------+--------------------+
| College of Engineering | Computer Science | 500000.0 | Intro to CS |
| College of Engineering | Computer Science | 500000.0 | Data Structures |
| College of Engineering | Mechanical Engineering | 400000.0 | Thermodynamics |
| College of Arts | Fine Arts | 200000.0 | Oil Painting |
+------------------------+------------------------+-------------------+--------------------+
La fonction GRAPH_EXPAND produit la table aplatie en appliquant une série d'opérations LEFT JOIN aux tables de nœuds et d'arêtes. Un graphique d'entrée valide doit
comporter exactement une table de nœuds racine, qui est une table dont la valeur KEY n'apparaît dans aucune autre table. Les données qui ne sont pas accessibles à partir de la table de nœuds racine via une série de jointures n'apparaissent pas dans la sortie. Dans l'exemple précédent, la table Course est la table de nœuds racine. Le département Research est omis de la sortie, car il ne comporte aucun cours.
Vous ne pouvez pas sélectionner directement une colonne pour une propriété définie par une mesure.
Vous devez plutôt l'encapsuler dans la
AGG() fonction.
Cette fonction garantit que l'agrégation définie sur les mesures est effectuée exactement une fois par clé.
La requête suivante calcule simultanément le budget total et le nombre total de cours pour chaque faculté :
SELECT
College_college_name,
AGG(Department_total_budget) AS college_budget,
AGG(Course_course_count) AS total_courses
FROM
GRAPH_EXPAND("university.SchoolGraph")
GROUP BY
College_college_name;
/*------------------------+----------------+---------------+
| College_college_name | college_budget | total_courses |
+------------------------+----------------+---------------+
| College of Engineering | 900000.0 | 3 |
| College of Arts | 200000.0 | 1 |
+------------------------+----------------+---------------*/
Bonnes pratiques
Lorsque vous concevez un graphique avec des mesures, suivez ces bonnes pratiques :
Définir des nœuds et des arêtes dans une seule table
Nous vous recommandons d'utiliser la même table pour une définition de table de nœuds et ses définitions de table d'arêtes de connexion. La réutilisation de la table garantit une relation un à un (1:1) exacte entre la table de nœuds et la table d'arêtes, ce qui empêche la distribution ramifiée et garantit que la fonction GRAPH_EXPAND n'ignore pas l'arête comme étant ambiguë.
Par exemple, si vous disposez d'une table d'entrée Enrollment contenant des clés étrangères pointant vers les tables Student et Course, définissez le nœud Enrollment et ses arêtes sortantes à l'aide de la table d'entrée Enrollment.
Modéliser les relations plusieurs à plusieurs en tant que tables de nœuds
Une relation plusieurs à plusieurs (M:N) se produit lorsqu'une ligne de la table A peut correspondre à plusieurs lignes de la table B, et qu'une ligne de la table B peut correspondre à plusieurs lignes de la table A. Par exemple, un étudiant peut s'inscrire à plusieurs cours et un cours peut avoir de nombreux étudiants. Vous pouvez séparer une relation plusieurs à plusieurs en deux relations un-à-plusieurs à l'aide d'une table de jonction intermédiaire. Par exemple, vous pouvez définir une table Enrollment contenant des clés étrangères pointant vers les tables Student et Course. Si vous modélisez une table de jonction intermédiaire en tant que table d'arêtes qui connecte deux tables de nœuds de dimension dans votre instruction CREATE PROPERTY GRAPH, la fonction GRAPH_EXPAND ignore ces arêtes, car leur relation est ambiguë : elle n'est pas clairement plusieurs à un ou un à un.
CREATE PROPERTY GRAPH university.SchoolGraph
NODE TABLES (
university.Student,
university.Course
)
EDGE TABLES (
-- Modeling the junction table as a standalone edge causes ambiguity
university.Enrollment AS StudentEnrollment
SOURCE KEY (student_id) REFERENCES Student (student_id)
DESTINATION KEY (course_id) REFERENCES Course (course_id)
);
La fonction GRAPH_EXPAND ignore ces arêtes, car elles sont ambiguës (elles ne sont pas clairement plusieurs à un ou un à un entre les tables de nœuds elles-mêmes). Si toutes les arêtes d'un graphique sont ignorées, les appels à GRAPH_EXPAND ou BQ.SHOW_GRAPH_EXPAND_SCHEMA échouent avec une erreur.
Pour modéliser correctement une relation M:N pour les mesures, promouvez la table de jonction intermédiaire en table de nœuds. Dans cette structure, la table de nœuds de jonction sert de table de nœuds racine unique (table de nœuds avec un degré entrant de zéro). Définissez ensuite deux tables d'arêtes plusieurs à un (N:1) qui partagent la table de jonction pour connecter N:1 à chacune des tables de nœuds de dimension :
CREATE PROPERTY GRAPH university.SchoolGraph
NODE TABLES (
university.Student KEY (student_id),
university.Course KEY (course_id),
-- Promote the junction table to a node table (acting as the single root node)
university.Enrollment KEY (enrollment_id)
)
EDGE TABLES (
-- Share (reuse) the Enrollment table to define N:1 edges to each dimension
university.Enrollment AS EnrollmentToStudent
SOURCE KEY (enrollment_id) REFERENCES Enrollment (enrollment_id)
DESTINATION KEY (student_id) REFERENCES Student (student_id),
university.Enrollment AS EnrollmentToCourse
SOURCE KEY (enrollment_id) REFERENCES Enrollment (enrollment_id)
DESTINATION KEY (course_id) REFERENCES Course (course_id)
);
Dans cette structure, Enrollment sert de table de nœuds racine unique (degré entrant de zéro) connectant N:1 aux tables de dimension Student et Course (degré entrant de un). La fonction GRAPH_EXPAND peut aplatir ce graphique en parcourant les données de Enrollment vers Student et Course. Si vous définissez des mesures sur l'une de ces tables, vous pouvez appeler la fonction AGG sur les colonnes de mesure pour calculer correctement les agrégations sans surcomptage.
Afficher le schéma GRAPH_EXPAND
Pour afficher le schéma de la table renvoyée par la GRAPH_EXPAND fonction
sans l'appeler, utilisez la
BQ.SHOW_GRAPH_EXPAND_SCHEMA procédure système :
DECLARE schema STRING DEFAULT '';
CALL BQ.SHOW_GRAPH_EXPAND_SCHEMA('university.SchoolGraph', schema);
SELECT schema;
Cette procédure remplit la variable schema avec le nom, le type et le mode de chaque colonne. Elle indique également si la propriété référencée par la colonne est une mesure, et liste toute description ou tout synonyme que vous avez défini sur celle-ci.
Étape suivante
- Découvrez comment créer et interroger un graphique de propriétés.
- Découvrez les schémas de graphiques.