2013-02-14 5 views
1

Nous essayons d'utiliser l'API Traversal pour récupérer, pour un ensemble donné de nœuds d'entreprise, uniquement les nœuds d'entreprise qui fournissent tous les produits contenus dans la liste des nœuds du produit. Les tentatives précédentes d'utiliser Cypher ne fonctionnaient pas bien. Dans cet exemple:Neo4j Traversal API limitation?

Company 1 provides product A and B 
Company 2 provides product A and B and C 
Company 3 provides product A and C 

Si les 3 sociétés sont incluses dans la requête de la liste des entreprises et des produits A et C sont dans la liste des produits en question, nous voulons retourné seulement Company 2 et 3, car ils fournissent le produit A et C . Voici notre requête:

for (Path position : Traversal.description() 
.depthFirst() 
.uniqueness(Uniqueness.NODE_GLOBAL) 
.relationships(Rels.PROVIDES_PRODUCT, Direction.OUTGOING) 
.evaluator((Evaluator) Evaluators.includeWhereEndNodeIs(productNodes)) 
.traverse(companyNodes)) 

Si nous utilisons le Evaluator.includeWhereEndNodeIs(productNodes) nous récupérons toutes les entreprises qui fournissent un des produits dans la liste productNodes (toutes les 3 entreprises dans l'exemple ci-dessus). Si nous utilisons l'évaluateur Evaluators.includeIfContainsAll(productNodes), nous ne récupérons aucun nœud de société s'il y a plusieurs produits dans la liste des nœuds de produit.

Toute suggestion appréciée.

+0

pouvez-vous ajouter la requête de chiffrement d'origine? Cela rendrait beaucoup plus facile de comprendre ce que vous voulez accomplir. –

+0

Michael - voici la requête originale de Cypher que nous avions - nous voulons seulement que les entreprises retournées fournissent tous les produits de la liste et que cette syntaxe ne fonctionne pas: START company = node (10719,37496,37417,37464), product = node (37512 , 65094) O WH société -> produit RETURN entreprise, produit; Merci –

Répondre

0

Je ne sais pas si c'est possible dans une instruction, mais vous pouvez les imbriquer. Company2 et Company3 seront retournés dans le cas suivant:

for (final Path position : Traversal 
      .description() 
      .depthFirst() 
      .uniqueness(Uniqueness.RELATIONSHIP_LEVEL) 
      .relationships(RelType.PROVIDES_PRODUCT, Direction.OUTGOING) 
      .evaluator(
        (Evaluator) Evaluators.endNodeIs(Evaluation.INCLUDE_AND_CONTINUE, Evaluation.EXCLUDE_AND_CONTINUE, 
          productA)).traverse(company1, company2, company3)) { 
     for (final Path position2 : Traversal 
       .description() 
       .depthFirst() 
       .uniqueness(Uniqueness.RELATIONSHIP_LEVEL) 
       .relationships(RelType.PROVIDES_PRODUCT, Direction.OUTGOING) 
       .evaluator(
         (Evaluator) Evaluators.endNodeIs(Evaluation.INCLUDE_AND_CONTINUE, Evaluation.EXCLUDE_AND_CONTINUE, 
           productC)).traverse(position.startNode())) { 
      System.out.println(position2.startNode()); 
     } 
} 
+0

Merci pour la réponse. Essayer ceci dehors - aucune chance pourtant bien que la syntaxe soit un peu difficile. –

0

sont la (société) - [: PROVIDES_PRODUCT] -> (produit) un seul niveau toujours? Dans ce cas, il serait bien avec une simple boucle comme ceci:

 
Set<Node> companies = new HashSet<Node>(asList(companyNodes)); 
for (Node product : productNodes) 
{ 
    Set<Node> companiesForThisProduct = new HashSet<Node>(); 
    for (Relationship rel : product.getRelationships(PROVIDES_PRODUCT, INCOMING)) 
     companiesForThisProduct.add(rel.getStartNode()); 
    companies.retainAll(companiesForThisProduct); 
} 

Je rapidement piraté votre exemple avec votre ensemble de données et il fonctionne très bien.