Hello,
j'utilise la librairie .NET
voici mon use-case:
J'ai un node A et B qui doivent être fusionnés car représentant la même entité.
Je crée donc un node C, puis copie les valeurs des nodes A & B dans C. J'aimerais ensuite copier (ou déplacer) toutes les relations pointant ou partant des nodes A & B vers C pour compléter cette fusion, et ce, dynamiquement, puisque ne sachant pas exactement quelles types de relations pointes sur A & B.
(a:Label)-[r]-() (b:Label)-[r2]-() (c:Label)
J'ai essayer différentes stratégies sans succès, tel que:
using (GraphClient graphClient = GetGraphClient()) { var inputString = string.Format("({0}:{1})-[r]->(n), ({2}:{3})", "a", typeof(Label).Name, "c", typeof(Label).Name); var query = graphClient.Cypher .SendQueryOnMaster() .Match(inputString) .Where((Label a) => a.Id == from.Id) .AndWhere((Label c) => c.Id == to.Id) .Create("(c)-[r2:type(r)]->(n)"); query.ExecuteWithoutResults(); }
Y-aurait-il une façon ou un moyen détourner de réaliser cette copie ?
Merci d'avance, Bastien.
Petite précision, j'utilise la version: 2.3.2 - ENTERPRISE de Neo4J
Bonjour Benoît,
merci pour votre réponse rapide,
A & B ont les mêmes propriétés, avec des valeurs différentes, et la fusion peut séléctionner aussi bien des champs de A que des champs de B dépendant de leur valeur, mais effectivement, on pourrait choisir un des deux nodes et mettre à jour les propriétés qui doivent l'être avec les propriétés du second node.
Par rapport à la variabilisation du type, le but était d'exécuter une seule requête Cypher (contrairement au FOR) pour des soucis d'optimisation (Latence), et l'OPTIONAL MATCH nécessiterait une mise à jour de la requête cypher à chaque fois qu'un nouveau type de relation serait rajoutée, pas idéal côté maintenabilité ^^
Quand vous parlez de la boucle FOR vous parlez bien d'une boucle FOR C# qui itèrerait la fonction copie de relation sur l'ensemble des noms de relations ?
Cordialement, Bastien.
Petite update, ça fonctionne nickel, voici mon code C# si jamais ça peut aider des gens dans le futur:
internal static void DuplicateRelationships<T>(T from, T to) where T : IDataObject{string aVariable = "a";string bVariable = "b";string nVariable = "n";string relationVariable = "r";string newRelation = "r2";string relationsVariable = "rels";string relationPostCollectVariable = "rel";
Guid fromId = from.Id;Guid toId = to.Id;
foreach (string relation in CypherVerbs.GetAllVerbs()){
using (GraphClient graphClient = GetGraphClient()){
/*-[r]->*/graphClient.Cypher.SendQueryOnMaster().Match(string.Format("({0}:{1})-[{2}:{3}]->({4}), ({5}:{6})", aVariable, from.GetType().Name, relationVariable, relation, nVariable, bVariable, to.GetType().Name)).Where((T a) => a.Id == fromId).AndWhere((T b) => b.Id == toId).With(string.Format("COLLECT({0}) AS {1}, {2}, {3}, {4}", relationVariable, relationsVariable, aVariable, bVariable, nVariable)).ForEach(string.Format("({0} in {1} | ", relationPostCollectVariable, relationsVariable)).Create(string.Format("({0})-[{1}:{2}]->({3})", bVariable, newRelation, relation, nVariable)).Set(string.Format("{0} += {1})", newRelation, relationPostCollectVariable)).ExecuteWithoutResults();
/*<-[r]-*/graphClient.Cypher.SendQueryOnMaster().Match(string.Format("({0}:{1})<-[{2}:{3}]-({4}), ({5}:{6})", aVariable, from.GetType().Name, relationVariable, relation, nVariable, bVariable, to.GetType().Name)).Where((T a) => a.Id == fromId).AndWhere((T b) => b.Id == toId).With(string.Format("COLLECT({0}) AS {1}, {2}, {3}, {4}", relationVariable, relationsVariable, aVariable, bVariable, nVariable)).ForEach(string.Format("({0} IN {1} | ", relationPostCollectVariable, relationsVariable)).Create(string.Format("({0})<-[{1}:{2}]-({3})", bVariable, newRelation, relation, nVariable)).Set(string.Format("{0} += {1})", newRelation, relationPostCollectVariable)).ExecuteWithoutResults();}}}
Le vendredi 15 avril 2016 11:21:46 UTC+2, Bastien Debret a écrit :Super, merci à vous pour le support, effectivement la release 3.0 offre pas mal de possibilités et va repondre à mon use-case ;)
Je vais faire les tests du FOR C#