我正在使用此示例http://neo4j.com/docs/stable/cypher-cookbook-newsfeed.html来维护用户的新闻源。所以我使用以下内容发布状态更新:
MATCH (me)
WHERE me.name='Bob'
OPTIONAL MATCH (me)-[r:STATUS]-(secondlatestupdate)
DELETE r
CREATE (me)-[:STATUS]->(latest_update { text:'Status',date:123 })
WITH latest_update, collect(secondlatestupdate) AS seconds
FOREACH (x IN seconds | CREATE (latest_update)-[:NEXT]->(x))
RETURN latest_update.text AS new_status
以下内容获取它们:
MATCH (me { name: 'Joe' })-[rels:FRIEND*0..1]-(myfriend)
WHERE ALL (r IN rels WHERE r.status = 'CONFIRMED')
WITH myfriend
MATCH (myfriend)-[:STATUS|:NEXT*0..2]-(statusupdates)
RETURN myfriend.name AS name, statusupdates.date AS date, statusupdates.text AS text
ORDER BY statusupdates.date DESC LIMIT 3
这看起来很简单。新闻源将包含我朋友的最新2个状态更新。但是,假设我们想要选择仅满足特定条件的statusupdates。例如:
MATCH (myfriend)-[:STATUS|:NEXT*0..2]-(statusupdates {type: "photo"})
这似乎有效。但是,如果用户在短时间内使用不同类型的最新2次更新发布4个状态更新,则此功能无效。
让我们说在4次更新中,最新的2是“url”类型,之前的2是“photo”类型。上面的新闻源提取代码只是忽略了这个用户,因为它看到来自该用户的最新2个状态更新不是“照片”类型,即使所有4个帖子都比其他用户的帖子更新。
答案 0 :(得分:2)
让我们在数据库中获取一些代表您情况的数据:
serializedlength
您的查询:
CREATE (n1:Update {id: 1, type: 'url'})
CREATE (n2:Update {id: 2, type: 'url'})
CREATE (n3:Update {id: 3, type: 'photo'})
CREATE (n4:Update {id: 4, type: 'url'})
CREATE (n5:Update {id: 5, type: 'photo'})
CREATE (n6:Update {id: 6, type: 'url'})
CREATE (n1)<-[:NEXT]-(n2)<-[:NEXT]-(n3)<-[:NEXT]-(n4)<-[:NEXT]-(n5)<-[:NEXT]-(n6)
CREATE (user:User)-[:STATUS]->(n1)
如果我们执行它,那么就像你说的那样我们得到'(没有行)'。
可能的解决方案:
MATCH (user:User) WITH user
MATCH (user)-[:STATUS|:NEXT*0..2]-(statuses:Update {type: "photo"})
RETURN user, statuses
此类解决方案的缺点:我们将遍历所有状态,然后才应用MATCH (user:User) WITH user
MATCH (user)-[:STATUS|:NEXT*]-(statuses:Update {type: "photo"})
RETURN statuses LIMIT 2
过滤器。
遍历是非常快速的操作。你可以做的是 - 将遍历深度与LIMIT
子句结合起来。例如:
LIMIT
这是所需数据和性能之间的妥协。
但是!或者,您可以做的是 - 为单独的更新类型创建其他关系链。
示例:
MATCH (user:User) WITH user
MATCH (user)-[:STATUS|:NEXT*0..100]-(statuses:Update {type: "photo"})
RETURN statuses LIMIT 2
优点:您可以以最高效的方式轻松获取必要的数据。
缺点:数据库中的数据模型变得更加复杂,需要额外的维护。