我们正在尝试使用Traversal API为给定的公司节点集检索仅提供产品节点列表中包含的所有产品的公司节点。之前使用Cypher的尝试表现不佳。在这个例子中:
Company 1 provides product A and B
Company 2 provides product A and B and C
Company 3 provides product A and C
如果所有3家公司都包含在公司列表查询中,并且产品A和C在查询中的产品列表中,我们希望仅返回公司2和3,因为它们提供产品A和C.这是我们的查询:
for ( Path position : Traversal.description()
.depthFirst()
.uniqueness(Uniqueness.NODE_GLOBAL)
.relationships(Rels.PROVIDES_PRODUCT, Direction.OUTGOING)
.evaluator((Evaluator) Evaluators.includeWhereEndNodeIs(productNodes))
.traverse(companyNodes))
如果我们使用Evaluator.includeWhereEndNodeIs(productNodes)
,我们会收回所有提供productNodes
列表中所有产品的公司(上例中的所有3家公司)。如果我们使用Evaluators.includeIfContainsAll(productNodes)
评估程序,如果产品节点列表中有多个产品,则不会返回任何公司节点。
任何建议表示赞赏。
答案 0 :(得分:0)
我不确定是否可以在一个声明中,但你可以嵌套它们。在下列情况下,公司2和公司3将被退回:
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());
}
}
答案 1 :(得分:0)
(公司) - [:PROVIDES_PRODUCT] - >(产品)总是只有一个级别吗?在这种情况下,使用这样的简单循环就可以了:
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 ); }
我很快用您的数据集破解了您的示例,它运行正常。