private function createAggregate(
        Identity $identity,
        object $entity,
        Query $query
    ): Query {
        $meta = ($this->metadata)(\get_class($entity));
        $data = ($this->extract)($entity);
        $varName = $this->name->sprintf(\md5($identity->value()));

        $query = $query->create(
            (string) $varName,
            $meta->labels()->toPrimitive()
        );
        $paramKey = $varName->append('_props');
        $properties = $this->buildProperties(
            $meta->properties(),
            $paramKey
        );
        $keysToKeep = $data->keys()->intersect($properties->keys());

        $query = $query
            ->withProperty(
                $meta->identity()->property(),
                (string) $paramKey
                    ->prepend('{')
                    ->append('}.')
                    ->append($meta->identity()->property())
            )
            ->withProperties($properties->reduce(
                [],
                static function(array $carry, string $property, string $cypher): array {
                    $carry[$property] = $cypher;

                    return $carry;
                }
            ))
            ->withParameter(
                (string) $paramKey,
                $data
                    ->filter(static function(string $key) use ($keysToKeep): bool {
                        return $keysToKeep->contains($key);
                    })
                    ->put(
                        $meta->identity()->property(),
                        $identity->value()
                    )
                    ->reduce(
                        [],
                        static function(array $carry, string $key, $value): array {
                            $carry[$key] = $value;

                            return $carry;
                        }
                    )
            );

        $query = $meta
            ->children()
            ->reduce(
                $query,
                function(Query $carry, string $property, Child $child) use ($varName, $data): Query {
                    return $this->createAggregateChild(
                        $child,
                        $varName,
                        $data->get($property),
                        $carry
                    );
                }
            );
        $this->variables = $this->variables->add((string) $varName);

        return $query;
    }