Neo4j 如何获取排除位置的用户总数=";“海得拉巴”;并包括设备品牌=”;列诺娃;?

Neo4j 如何获取排除位置的用户总数=";“海得拉巴”;并包括设备品牌=”;列诺娃;?,neo4j,Neo4j,我使用的是neo4j版本3.0.3。我已经执行了下面的查询。它给出的结果是拥有HAS_visted_位置关系的用户数,但我还需要没有HAS_visted_位置关系的用户总数 MATCH (c:Consumer)-[:HAS_VISITED_LOCATION]-(l:Location) WHERE NOT l.AreaName="hyderabad" MATCH(c)-[:HAS_DEVICE_BRAND]-(d:DeviceBrand{BrandName:"lenovo"}) RETURN

我使用的是neo4j版本3.0.3。我已经执行了下面的查询。它给出的结果是拥有HAS_visted_位置关系的用户数,但我还需要没有HAS_visted_位置关系的用户总数

MATCH (c:Consumer)-[:HAS_VISITED_LOCATION]-(l:Location) 
WHERE NOT l.AreaName="hyderabad" 
MATCH(c)-[:HAS_DEVICE_BRAND]-(d:DeviceBrand{BrandName:"lenovo"}) 
RETURN count(c) 

因此,您需要计算所有拥有联想设备品牌且未访问海得拉巴的消费者的数量

此查询应执行以下操作:

MATCH (l:Location {AreaName:'hyderabad'})
MATCH (c:Consumer)-[:HAS_DEVICE_BRAND]->(:DeviceBrand{BrandName:"lenovo"}) 
WHERE NOT (c)-[:HAS_VISITED_LOCATION]->(l)
RETURN COUNT(DISTINCT c) 
编辑-新的(但相关的)问题,关于如何吸引没有去过海得拉巴和没有联想品牌的消费者

这个新问题更为棘手,因为它与没有关系的情况相匹配

直截了当的方法是简单地匹配那些消费者没有去过海得拉巴并且没有lenevo设备品牌的消费者:

MATCH (c:Consumer)
WHERE NOT (c)-[:HAS_VISITED_LOCATION]->(l:Location {AreaName:'hyderabad'})
AND NOT (c)-[:HAS_DEVICE_BRAND]->(:DeviceBrand{BrandName:"lenovo"}) 
RETURN COUNT(c) as count
虽然这是正确的,但它可能不是最有效的查询

如果我们查看所需内容的逻辑表示,我们可能会看到另一种方法:

// first get the total count of consumers, should be very fast
MATCH (c:Consumer)
WITH COUNT(c) as totalCount
MATCH (lenovo:DeviceBrand{BrandName:'lenevo'}), (hyderabad:Location{AreaName:'hyderabad'})
// union lenevo and hyderabad into one column through collecting and combining and unwinding
// (this is a workaround since Cypher can't do post-union processing)
WITH totalCount, COLLECT(lenevo) + COLLECT(hyderabad) as excludeNodes
UNWIND excludeNodes as excludeNode
// get all consumers attached to these nodes
MATCH (excludeNode)<-[:HAS_DEVICE_BRAND|:HAS_VISITED_LOCATION]-(c:Consumer)
WITH totalCount, COUNT(DISTINCT c) as excludeCount
RETURN totalCount - excludeCount as count
没有(参观过海得拉巴)也没有(参观过列涅沃)

如果我们否定您的要求:

没有(没有(参观过海得拉巴)和没有(有过列涅沃))=(参观过 海得拉巴)或(有勒涅沃)

因此,另一个查询可以是找到你想要的否定的计数(访问海得拉巴或联想的消费者计数),然后从消费者总数中减去它,得到你想要的实际计数

您可以尝试此查询,看看它是否比直截了当的方法性能更好:

// first get the total count of consumers, should be very fast
MATCH (c:Consumer)
WITH COUNT(c) as totalCount
MATCH (lenovo:DeviceBrand{BrandName:'lenevo'}), (hyderabad:Location{AreaName:'hyderabad'})
// union lenevo and hyderabad into one column through collecting and combining and unwinding
// (this is a workaround since Cypher can't do post-union processing)
WITH totalCount, COLLECT(lenevo) + COLLECT(hyderabad) as excludeNodes
UNWIND excludeNodes as excludeNode
// get all consumers attached to these nodes
MATCH (excludeNode)<-[:HAS_DEVICE_BRAND|:HAS_VISITED_LOCATION]-(c:Consumer)
WITH totalCount, COUNT(DISTINCT c) as excludeCount
RETURN totalCount - excludeCount as count
//首先获取消费者总数,应该非常快
匹配(c:消费者)
将计数(c)作为totalCount
匹配(联想:设备品牌{BrandName:'lenevo'}),(海得拉巴:地点{AreaName:'hyderabad'})
//通过收集、合并和展开,将列涅沃和海得拉巴合并为一列
//(这是一个解决办法,因为Cypher无法进行工会后处理)
使用totalCount,COLLECT(lenevo)+COLLECT(hyderabad)作为excludeNodes
将excludeNodes作为excludeNode展开
//将所有使用者连接到这些节点

MATCH(excludeNode)请记住,您的查询没有执行您认为它正在执行的操作。如果消费者访问过其他地点以及海得拉巴,他们将包括在您的第一次匹配中(它将只匹配到非海得拉巴的一个地点)。此外,消费者会在他们访问过的非海得拉巴地区出现多次,每次一次,因此您的计数将不准确。是的,我想统计所有拥有联想设备品牌且未访问过海得拉巴的消费者。太好了,我的答案中的查询应该正好如此。是的,您的查询给出了准确的结果。谢谢如果我想在同一查询中排除另一个节点,我必须做什么?请看我的查询的第3行,
WHERE NOT…
您可能会在其下方添加类似的行,以排除消费者与其他节点之间的关系:
和NOT…
然后附加要排除的模式。