/**
* @param string $key
* @param mixed $value
*
* @throws \GraphAware\Neo4j\Client\Exception\Neo4jException
*
* @return object[]
*/
public function findBy($key, $value, $isId = false)
{
$label = $this->classMetadata->getLabel();
$idId = $isId ? 'id(n)' : sprintf('n.%s', $key);
$query = sprintf('MATCH (n:%s) WHERE %s = {%s}', $label, $idId, $key);
/** @var \GraphAware\Neo4j\OGM\Metadata\RelationshipMetadata[] $associations */
$associations = $this->classMetadata->getNonLazyRelationships();
$assocReturns = [];
foreach ($associations as $identifier => $association) {
$type = $association->isRelationshipEntity() ? $this->entityManager->getRelationshipEntityMetadata($association->getRelationshipEntityClass())->getType() : $association->getType();
switch ($association->getDirection()) {
case 'INCOMING':
$relStr = '<-[rel_%s:%s]-';
break;
case 'OUTGOING':
$relStr = '-[rel_%s:%s]->';
break;
default:
$relStr = '-[rel_%s:%s]-';
break;
}
$relationshipIdentifier = sprintf('%s_%s', strtolower($association->getPropertyName()), strtolower($type));
$relQueryPart = sprintf($relStr, $relationshipIdentifier, $type);
$query .= PHP_EOL;
$query .= 'OPTIONAL MATCH (n)' . $relQueryPart . '(' . $association->getPropertyName() . ')';
$query .= ' WITH n, ';
$query .= implode(', ', $assocReturns);
if (!empty($assocReturns)) {
$query .= ', ';
}
$relid = 'rel_' . $relationshipIdentifier;
if ($association->hasOrderBy()) {
$orderProperty = $association->getPropertyName() . '.' . $association->getOrderByPropery();
if ($association->isRelationshipEntity()) {
$reMetadata = $this->entityManager->getRelationshipEntityMetadata($association->getRelationshipEntityClass());
$split = explode('.', $association->getOrderByPropery());
if (count($split) > 1) {
$reName = $split[0];
$v = $split[1];
if ($reMetadata->getStartNodePropertyName() === $reName || $reMetadata->getEndNodePropertyName() === $reName) {
$orderProperty = $association->getPropertyName() . '.' . $v;
}
} else {
if (null !== $reMetadata->getPropertyMetadata($association->getOrderByPropery())) {
$orderProperty = $relid . '.' . $association->getOrderByPropery();
}
}
}
$query .= $relid . ', ' . $association->getPropertyName() . ' ORDER BY ' . $orderProperty . ' ' . $association->getOrder();
$query .= PHP_EOL;
$query .= ' WITH n, ';
$query .= implode(', ', $assocReturns);
if (!empty($assocReturns)) {
$query .= ', ';
}
}
if ($association->isCollection() || $association->isRelationshipEntity()) {
$query .= sprintf(' CASE count(%s) WHEN 0 THEN [] ELSE collect({start:startNode(%s), end:endNode(%s), rel:%s}) END as %s', $relid, $relid, $relid, $relid, $relid);
$assocReturns[] = $relid;
} else {
$query .= $association->getPropertyName();
$assocReturns[] = $association->getPropertyName();
}
}
$query .= PHP_EOL;
$query .= 'RETURN n';
if (!empty($assocReturns)) {
$query .= ', ' . implode(', ', $assocReturns);
}
//print_r($query);
$parameters = [$key => $value];
$result = $this->entityManager->getDatabaseDriver()->run($query, $parameters);
return $this->hydrateResultSet($result);
}