Trabaja con medidas

En este documento, se muestra cómo definir y consultar medidas en tus gráficos. Puedes usar medidas para asegurarte de que las agregaciones se realicen correctamente en las uniones.

Descripción general

Una medida es una propiedad agregada definida dentro de la cláusula PROPERTIES de una tabla de nodos o aristas. Las medidas se definen con la palabra clave MEASURE y una de las siguientes funciones agregadas compatibles:

  • SUM
  • AVG
  • COUNT
  • COUNT(DISTINCT)
  • MIN
  • MAX

Las medidas definen su agregación en referencia a la KEY de la tabla de nodos o aristas en la que se definen. Esto significa que, cuando consultas una medida, la agregación se realiza correctamente, incluso si la tabla subyacente se une de una manera que hace que se dupliquen las filas.

No puedes hacer referencia a una propiedad definida por una medida en una consulta de GQL. En cambio, puedes acceder a las medidas llamando a la GRAPH_EXPAND TVF para crear una representación de tabla aplanada de tu gráfico. Esta función no acepta todos los tipos de gráficos. Para obtener más información sobre qué grafos forman una entrada válida, consulta las limitaciones de entrada.

Puedes llamar a la AGG función en el resultado de la GRAPH_EXPAND TVF para agregar las propiedades según la función de agregación que definiste en la medida.

Define medidas

Para definir medidas, usa la palabra clave MEASURE() alrededor de una función de agregación compatible dentro de la cláusula PROPERTIESde una definición de tabla de nodos o aristas.

En el siguiente ejemplo, se crea un conjunto de datos llamado university y tablas para universidades, departamentos y cursos:

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);

La siguiente instrucción crea un gráfico llamado SchoolGraph que define medidas en algunas de las propiedades de los nodos Department y Course. Debes proporcionar un alias para las propiedades definidas por una medida.

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)
  );

Visualización del gráfico de SchoolGraph.

La medida total_budget se define como MEASURE(SUM(budget)). La medida bloquea la agregación en la KEY, que es dept_id.

Información sobre el recuento excesivo

Cuando unes tablas, los datos se repiten cada vez que hay una relación de uno a varios en tus datos. Por ejemplo, si unes las tablas Course, Department y College, un departamento con varios cursos aparece en varias filas del resultado:

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 intentas calcular el presupuesto total por universidad con SUM(budget), el presupuesto del departamento de Ciencias de la Computación se cuenta dos veces. Puedes evitar este problema consultando la tabla Department directamente, pero este enfoque no funciona si deseas calcular varias agregaciones de diferentes tablas que contribuyen a tus datos unidos. En la siguiente sección, se muestra cómo las medidas resuelven este problema.

Consulta un gráfico con medidas

Puedes consultar un gráfico con medidas mediante GQL, pero tu consulta no puede hacer referencia directa a ninguna propiedad definida por una medida. Por ejemplo, la siguiente consulta hace referencia a nodos que tienen propiedades de medida definidas, pero no usa ni muestra ninguno de los campos de medida:

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    |
 +------------------------+------------------------+-----------------*/

Trabaja con medidas

Para trabajar con medidas, usa la GRAPH_EXPAND función con valor de tabla (TVF) para consultar tu gráfico como una sola tabla aplanada. Las columnas de la tabla de salida se derivan de las propiedades definidas en el grafo para cada tabla de nodos y aristas. Para evitar conflictos de nombres, las columnas se nombran concatenando la etiqueta de la tabla de nodos o aristas y el nombre de la propiedad, por ejemplo, Course_course_name o Department_total_budget. La siguiente consulta muestra algunos ejemplos de resultados 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 función GRAPH_EXPAND produce la tabla aplanada aplicando una serie de operaciones LEFT JOIN a las tablas de nodos y aristas. Un gráfico de entrada válido debe tener exactamente una tabla de nodos raíz, que es una tabla cuyo KEY valor no aparece en ninguna otra tabla. Los datos a los que no se puede acceder desde la tabla de nodos raíz a través de una serie de uniones no aparecen en el resultado. En el ejemplo anterior, la tabla Course es la tabla de nodos raíz. El departamento de Research se omite del resultado porque no tiene ningún curso.

No puedes seleccionar directamente una columna para una propiedad definida por una medida. En cambio, debes incluirlas en la AGG() función. Esta función garantiza que la agregación definida en las medidas se realice exactamente una vez por clave.

La siguiente consulta calcula simultáneamente el presupuesto total y la cantidad total de cursos para cada universidad:

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             |
 +------------------------+----------------+---------------*/

Visualiza el esquema de GRAPH_EXPAND

Para ver el esquema de la tabla que muestra la función GRAPH_EXPANDsin llamar a la función, usa elBQ.SHOW_GRAPH_EXPAND_SCHEMA procedimiento del sistema:

DECLARE schema STRING DEFAULT '';
CALL BQ.SHOW_GRAPH_EXPAND_SCHEMA('university.SchoolGraph', schema);
SELECT schema;

Este procedimiento propaga la variable schema con el nombre, el tipo y el modo de cada columna. También indica si la propiedad a la que hace referencia la columna es una medida y enumera cualquier descripción o sinónimo que hayas definido en ella.

¿Qué sigue?