Mit Messwerten arbeiten
In diesem Dokument wird beschrieben, wie Sie Messwerte in Ihren Graphen definieren und abfragen. Mit Messwerten können Sie dafür sorgen, dass Aggregationen bei Joins korrekt ausgeführt werden.
Übersicht
Ein Messwert ist eine aggregierte Property, die in der PROPERTIES-Klausel einer Knoten- oder Edge-Tabelle definiert ist. Messwerte werden mit dem Schlüsselwort MEASURE und einer der folgenden unterstützten Aggregatfunktionen definiert:
SUMAVGCOUNTCOUNT(DISTINCT)MINMAX
Messwerte definieren ihre Aggregation in Bezug auf den KEY der Knoten- oder Edge-Tabelle, in der sie definiert sind. Wenn Sie einen Messwert abfragen, wird die Aggregation also auch dann korrekt ausgeführt, wenn die zugrunde liegende Tabelle so verknüpft ist, dass Zeilen dupliziert werden.
Sie können in einer GQL-Abfrage nicht auf eine Property verweisen, die durch einen Messwert definiert ist. Stattdessen
greifen Sie auf Messwerte zu, indem Sie die
GRAPH_EXPAND TVF
aufrufen, um eine vereinfachte Tabellendarstellung Ihres Graphen zu erstellen. Diese Funktion akzeptiert nicht alle Arten von Graphen. Weitere Informationen dazu,
welche Graphen als gültige Eingabe dienen, finden Sie unter den Eingabebeschränkungen.
Sie können die
AGG Funktion
auf die Ausgabe der GRAPH_EXPAND TVF anwenden, um die Properties gemäß der Aggregatfunktion zu aggregieren, die Sie im
Messwert definiert haben.
Messwerte definieren
Sie definieren Messwerte in der
PROPERTIES Klausel
einer Knoten- oder Edge-Tabellendefinition, indem Sie das MEASURE() Schlüsselwort um eine
unterstützte Aggregatfunktion verwenden.
Im folgenden Beispiel wird ein Dataset namens university und Tabellen für Colleges, Abteilungen und Kurse erstellt:
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);
Mit der folgenden Anweisung wird ein Graph namens SchoolGraph erstellt, der Messwerte für einige der Properties in den Knoten Department und Course definiert.
Sie müssen einen Alias für Properties angeben, die durch einen Messwert definiert sind.
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)
);

Der Messwert total_budget ist als MEASURE(SUM(budget)) definiert. Der Messwert sperrt die Aggregation für den KEY, der dept_id ist.
Überzählung
Wenn Sie Tabellen verknüpfen, werden Daten jedes Mal wiederholt, wenn in Ihren Daten eine 1:n-Beziehung vorhanden ist. Wenn Sie beispielsweise die Tabellen Course, Department und College verknüpfen, wird eine Abteilung mit mehreren Kursen in mehreren Zeilen in der Ausgabe angezeigt:
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 |
+------------------------+------------------------+-----------------+----------*/
Wenn Sie versuchen, das Gesamtbudget pro College mit SUM(budget) zu berechnen, wird das Budget der Abteilung für Informatik zweimal gezählt. Sie können dieses Problem vermeiden, indem Sie die Tabelle Department direkt abfragen. Dieser Ansatz funktioniert jedoch nicht, wenn Sie mehrere Aggregationen aus verschiedenen Tabellen berechnen möchten, die zu Ihren verknüpften Daten beitragen. Im folgenden Abschnitt wird beschrieben, wie Messwerte dieses Problem lösen.
Graph mit Messwerten abfragen
Sie können einen Graphen mit Messwerten mit GQL abfragen. In Ihrer Abfrage kann jedoch nicht direkt auf eine Property verwiesen werden, die durch einen Messwert definiert ist. Die folgende Abfrage verweist beispielsweise auf Knoten, für die Messwert-Properties definiert sind, verwendet oder gibt aber keine der Messwertfelder zurück:
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 |
+------------------------+------------------------+-----------------*/
Mit Messwerten arbeiten
Wenn Sie mit Messwerten arbeiten möchten, verwenden Sie die
GRAPH_EXPAND
Tabellenwertfunktion (TVF)
, um Ihren Graphen als einzelne vereinfachte Tabelle abzufragen.
Die Spalten in der Ausgabetabelle werden aus den Properties abgeleitet, die im Graphen für jede Knoten- und Edge-Tabelle definiert sind. Um Namenskonflikte zu vermeiden, werden Spalten benannt, indem das Label der Knoten- oder Edge-Tabelle und der Property-Name verkettet werden, z. B. Course_course_name oder Department_total_budget. Die folgende Abfrage zeigt eine Beispielausgabe der 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 |
+------------------------+------------------------+-------------------+--------------------+
Die Funktion GRAPH_EXPAND erstellt die vereinfachte Tabelle, indem sie eine Reihe von LEFT JOIN-Vorgängen auf Knoten- und Edge-Tabellen anwendet. Ein gültiger Eingabegraph muss
genau eine Stammknotentabelle haben. Das ist eine Tabelle, deren KEY Wert in keiner anderen Tabelle vorkommt. Daten, die nicht über eine Reihe von Joins von der Stammknotentabelle aus erreichbar sind, werden nicht in der Ausgabe angezeigt. Im vorherigen Beispiel ist die Tabelle Course die Stammknotentabelle. Die Abteilung Research wird in der Ausgabe nicht berücksichtigt, da sie keine Kurse hat.
Sie können keine Spalte für eine Property auswählen, die durch einen Messwert definiert ist.
Stattdessen müssen Sie sie in die
AGG() Funktion einschließen.
Diese Funktion sorgt dafür, dass die für die Messwerte definierte Aggregation genau einmal pro Schlüssel ausgeführt wird.
Die folgende Abfrage berechnet gleichzeitig das Gesamtbudget und die Gesamtzahl der Kurse für jedes College:
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 |
+------------------------+----------------+---------------*/
Best Practices
Beachten Sie beim Entwerfen eines Graphen mit Messwerten die folgenden Best Practices:
Knoten und Edges in einer einzelnen Tabelle definieren
Wir empfehlen, dieselbe Tabelle für eine Knotentabellendefinition und die Definitionen der zugehörigen Edge-Tabellen zu verwenden. Durch die Wiederverwendung der Tabelle wird eine genaue 1:1-Beziehung zwischen der Knotentabelle und der Edge-Tabelle sichergestellt. So wird eine Fan-out-Situation verhindert und die Funktion GRAPH_EXPAND ignoriert die Edge nicht als mehrdeutig.
Wenn Sie beispielsweise eine Eingabetabelle Enrollment haben, die Fremdschlüssel enthält, die auf die Tabellen Student und Course verweisen, definieren Sie den Knoten Enrollment und seine ausgehenden Edges mit der Eingabetabelle Enrollment.
Viele-zu-viele-Beziehungen als Knotentabellen modellieren
Eine Viele-zu-viele-Beziehung (M:N) liegt vor, wenn eine Zeile in Tabelle A mehreren Zeilen in Tabelle B entsprechen kann und eine Zeile in Tabelle B mehreren Zeilen in Tabelle A entsprechen kann. Ein Student kann sich beispielsweise für mehrere Kurse anmelden und ein Kurs kann viele Studenten haben. Sie können eine Viele-zu-viele-Beziehung in zwei 1:n-Beziehungen aufteilen, indem Sie eine Zwischentabelle verwenden. Sie können beispielsweise eine Tabelle Enrollment definieren, die Fremdschlüssel enthält, die auf die Tabellen Student und Course verweisen. Wenn Sie eine Zwischentabelle als Edge-Tabelle modellieren, die zwei Dimensionsknotentabellen in Ihrer CREATE PROPERTY GRAPH-Anweisung verbindet, ignoriert die Funktion GRAPH_EXPAND diese Edges, da ihre Beziehung mehrdeutig ist: Sie ist nicht eindeutig eine Viele-zu-eins- oder eine Eins-zu-eins-Beziehung.
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)
);
Die Funktion GRAPH_EXPAND ignoriert diese Edges, da sie mehrdeutig sind (nicht eindeutig Viele-zu-eins oder Eins-zu-eins zwischen den Knotentabellen selbst). Wenn alle Edges in einem Graphen ignoriert werden, schlagen Aufrufe von GRAPH_EXPAND oder BQ.SHOW_GRAPH_EXPAND_SCHEMA mit einem Fehler fehl.
Um eine M:N-Beziehung für Messwerte korrekt zu modellieren, müssen Sie die Zwischentabelle in eine Knotentabelle umwandeln. In dieser Struktur dient die Zwischentabelle als einzige Stammknotentabelle (eine Knotentabelle mit einem Eingangsgrad von null). Definieren Sie dann zwei Viele-zu-eins-Edge-Tabellen (N:1), die die Zwischentabelle gemeinsam nutzen, um N:1 mit jeder der Dimensionsknotentabellen zu verbinden:
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)
);
In dieser Struktur dient Enrollment als einzige Stammknotentabelle (Eingangsgrad von null), die N:1 mit den Dimensionstabellen Student und Course verbindet (Eingangsgrad von eins). Die Funktion GRAPH_EXPAND kann diesen Graphen vereinfachen, indem sie von Enrollment nach außen zu Student und Course wechselt. Wenn Sie Messwerte für eine dieser Tabellen definieren, können Sie die Funktion AGG für die Messwertspalten aufrufen, um die Aggregationen korrekt zu berechnen, ohne Überzählung.
GRAPH_EXPAND-Schema ansehen
Wenn Sie das Schema der Tabelle ansehen möchten, die von der GRAPH_EXPAND Funktion
zurückgegeben wird, ohne die Funktion aufzurufen, verwenden Sie die
BQ.SHOW_GRAPH_EXPAND_SCHEMA Systemprozedur:
DECLARE schema STRING DEFAULT '';
CALL BQ.SHOW_GRAPH_EXPAND_SCHEMA('university.SchoolGraph', schema);
SELECT schema;
Diese Prozedur füllt die Variable schema mit dem Namen, Typ und Modus jeder Spalte. Außerdem wird angegeben, ob die von der Spalte referenzierte Property ein Messwert ist, und alle Beschreibungen oder Synonyme aufgeführt, die Sie dafür definiert haben.
Nächste Schritte
- Informationen zum Erstellen und Abfragen eines Property-Graphen .
- Informationen zu Graphenschemas.