Question

J'ai une requête comme celle-ci :

MATCH left, right 
WHERE (ID(right) IN [1, 2, 3] AND ID(left) IN [4, 5, 6]) 
WITH left, right 
  LIMIT 1 
RETURN left, right 
UNION MATCH left, right 
WHERE (ID(right) IN [1, 2, 3] AND ID(left) IN [4, 5, 6]) 
WITH left, right 
  SKIP 4 LIMIT 1 
RETURN left, right 
UNION MATCH left, right 
WHERE (ID(right) IN [1, 2, 3] AND ID(left) IN [4, 5, 6]) 
WITH left, right 
  SKIP 8 LIMIT 1 
RETURN left, right
CREATE UNIQUE left-[rel:FRIEND]->right 
RETURN rel;

En général, je crée simplement un ensemble de données afin de pouvoir l'utiliser plus tard dans l'instruction CREATE UNIQUE.
Évidemment, cela ne fonctionne pas - l'analyseur de requêtes dit que je ne peux utiliser la clause RETURN qu'une seule fois.Ma question est la suivante : comment composer un ensemble de données dans ce cas ?J'ai essayé d'attribuer un alias et de l'utiliser dans CREATE UNIQUE - je n'arrive pas non plus à le faire fonctionner.Qu'est-ce que je fais mal?Ce scénario est-il même possible ?

Était-ce utile?

La solution

Je comprends peut-être mal ce que vous recherchez, mais voici ce qui me vient à l'esprit lorsque je regarde votre requête.

Pour commencer, voici une adaptation de votre requête qui utilise SKIP et LIMIT sans RETURN ou UNION.

MATCH left, right
WHERE ID(left) IN [1,2,3] AND ID(right) IN [4,5,6]
WITH left, right 
    LIMIT 1
CREATE UNIQUE left-[rel:FRIEND]->right
WITH [rel] as rels  //If you want to return the relationship later you can put it in a collection and bring it WITH
MATCH left, right
WHERE ID(left) IN [1,2,3] AND ID(right) IN [4,5,6]
WITH left, right, rels 
    SKIP 4 LIMIT 1
CREATE UNIQUE left-[rel:FRIEND]->right
WITH rels + [rel] as rels
MATCH left, right
WHERE ID(left) IN [1,2,3] AND ID(right) IN [4,5,6]
WITH left, right, rels 
    SKIP 8 LIMIT 1
CREATE UNIQUE left-[rel:FRIEND]->right
WITH rels + [rel] as rels
RETURN LENGTH(rels), rels  // You can return the relationships here but SKIP/LIMIT does its job also if you don't return anything

Mais cette requête est un peu sauvage.Il s'agit en réalité de trois requêtes, dont deux ont été artificiellement insérées en tant que sous-requêtes de la première.Il fait correspondre à nouveau les mêmes nœuds dans chaque sous-requête, et il n'y a vraiment rien de gagné à exécuter les requêtes de cette façon plutôt que séparément (c'est en fait plus lent, car dans chaque sous-requête, vous faites également correspondre les nœuds que vous savez que vous n'utiliserez pas) .

Ma première suggestion est donc d'utiliser START au lieu de MATCH...WHERE lors de l'obtention de nœuds par identifiant.Dans l'état actuel des choses, la requête lie chaque nœud de la base de données comme "gauche", puis chaque nœud de la base de données comme "droite", puis filtre tous les nœuds liés à "gauche" qui ne correspondent pas à la condition. le WHERE clause, puis la même chose pour « droit ».Étant donné que cette partie de la requête est répétée trois fois, tous les nœuds de la base de données sont liés six fois au total.Cela coûte cher pour créer trois relations.Si tu utilises START vous pouvez lier les nœuds de votre choix immédiatement.Cela ne répond pas vraiment à votre question, mais ce sera plus rapide et la requête sera plus propre.Alors, utilisez START pour obtenir les nœuds par leur identifiant interne.

START left = node(1,2,3), right = node(4,5,6)

La deuxième chose à laquelle je pense est la différence entre les nœuds et les « chemins » ou « éléments de résultat » lorsque vous faites correspondre des modèles.Lorsque vous liez trois nœuds en "gauche" et trois autres nœuds en "droite", vous n'avez pas trois éléments de résultat, mais neuf.Pour chaque nœud lié à "gauche", vous obtenez trois résultats, car il existe trois "droites" possibles avec lesquelles le combiner.Si vous vouliez relier chaque « gauche » à chaque « droite », parfait.Mais je pense que ce que vous recherchez, ce sont les éléments de résultat (1),(4), (2),(5), (3),(6), et bien qu'il semble pratique de lier les trois nœuds "gauche" et les trois nœuds "droit" dans une seule requête avec des collections d'identifiants de nœuds, vous devez ensuite effectuer tout ce filtrage pour vous débarrasser des 6 correspondances indésirables.La requête devient complexe et lourde, et elle est en fait plus lente que l'exécution des requêtes séparément.Une autre façon de dire ceci est de dire que (1)-[:FRIEND]->(4) est un modèle distinct, non (pertinemment) connecté aux autres modèles que vous créez.Ce serait différent si vous vouliez créer (1)-[:FRIEND]->(2)<-[:FRIEND]-(3), alors vous voudriez gérer ces trois nœuds ensemble.Peut-être que vous explorez simplement les utilisations marginales du chiffrement, mais j'ai pensé que je devrais le souligner.D'ailleurs, en utilisant SKIP et LIMIT de cette manière, c'est un peu faux, ils ne sont pas vraiment destinés à la correspondance de modèles et au filtrage.C'est également imprévisible, à moins que vous n'utilisiez également ORDER BY, car rien ne garantit que les résultats seront dans un certain ordre.Vous ne savez pas quel élément de résultat est transmis.Quoi qu'il en soit, dans ce cas, je pense qu'il serait préférable de lier les nœuds et de créer la relation en trois requêtes distinctes.

START left = node(1), right = node(4)
CREATE UNIQUE left-[rel:FRIEND]->right
RETURN rel

START left = node(2), right = node(5)
CREATE UNIQUE left-[rel:FRIEND]->right
RETURN rel

START left = node(3), right = node(6)
CREATE UNIQUE left-[rel:FRIEND]->right
RETURN rel

Puisque vous savez déjà que vous voulez ces trois paires, et non, disons, (1),(4),(1),(5),(1),(6) il serait logique d'interroger uniquement ces paires, et le moyen le plus simple est d'interroger séparément.

Mais troisièmement, puisque les trois requêtes sont structurellement identiques, ne différant que par la valeur de la propriété (si id doit être considéré comme une propriété), vous pouvez simplifier la requête en généralisant ou en anonymisant ce qui les distingue, c'est-à-direutiliser des paramètres.

START left = node({leftId}), right = node({rightId})
CREATE UNIQUE left-[rel:FRIEND]->right
RETURN rel

parameters: {leftId:1, rightId:4}, {leftId:2, rightId:5}, {leftId:3, rightId:6}

Puisque la structure est identique, cypher peut mettre en cache le plan d’exécution.Cela permet d'obtenir de bonnes performances et la requête est ordonnée, maintenable et peut être facilement étendue si vous souhaitez ultérieurement effectuer la même opération sur d'autres paires de nœuds.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top