查询使 Twitter 流应用程序在保存数据时速度太慢
Queries make Twitter-stream application too slow in saving data
我有一个应用程序可以流式传输存储在 Neo4j 数据库中的 Twitter 数据。我存储的数据涉及推文、用户、主题标签及其关系(用户发布推文、推文标签主题标签、用户转发推文)。
现在,每次我收到一条新推文时,我所做的是:
- 检查数据库是否已经包含推文:如果是,我用新信息更新它(转推计数,如计数),否则我保存它
- 检查数据库是否已经包含用户:如果是,我用新信息更新它,否则我保存它
- 检查数据库是否已经包含主题标签:如果没有,我添加它
以此类推,保存关系的过程相同。
查询如下:
static String cqlAddTweet = "merge (n:Tweet{tweet_id: {2}}) on create set n.text={1}, n.location={3}, n.likecount={4}, n.retweetcount={5}, n.topic={6}, n.created_at={7} on match set n.likecount={4}, n.retweetcount={5}";
static String cqlAddHT = "merge (n:Hashtag{text:{1}})";
static String cqlHTToTweet = "match (n:Tweet),(m:Hashtag) where n.tweet_id={1} and m.text={2} merge (n)-[:TAGS]->(m)";
static String cqlAddUser = "merge (n:User{user_id:{3}}) on create set n.name={1}, n.username={2}, n.followers={4}, n.following={5}, n.profilePic={6} on match set n.name={1}, n.username={2}, n.followers={4}, n.following={5}, n.profilePic={6}";
static String cqlUserToTweet = "match (n:User),(m:Tweet) where m.tweet_id={2} and n.user_id={1} merge (n)-[:POSTS]->(m)";
static String cqlUserRetweets = "match (n:Tweet{tweet_id:{1}}), (u:User{user_id:{2}}) create (u)-[:RETWEETS]->(n)";
因为保存数据的速度很慢,我想如果我不运行所有那些每次都扫描数据的查询,这个系统会有更好的性能。
您对我的申请有什么建议吗?
谢谢你,如果这看起来很愚蠢,请提前原谅我。
确保在以下 label/property 对中有 indexes (or uniqueness constraints,如果合适)。这将使您的查询避免扫描具有相同标签的所有节点(在开始查询时)。
:Tweet(tweet_id)
:Hashtag(text)
:User(user_id)
顺便说一下,可以简化您的几个查询(但这应该不会影响性能):
static String cqlAddTweet = "MERGE (n:Tweet{tweet_id: {2}}) ON CREATE SET n.text={1}, n.location={3}, n.topic={6}, n.created_at={7} SET n.likecount={4}, n.retweetcount={5}";
static String cqlAddUser = "MERGE (n:User{user_id:{3}}) SET n.name={1}, n.username={2}, n.followers={4}, n.following={5}, n.profilePic={6}";
我有一个应用程序可以流式传输存储在 Neo4j 数据库中的 Twitter 数据。我存储的数据涉及推文、用户、主题标签及其关系(用户发布推文、推文标签主题标签、用户转发推文)。 现在,每次我收到一条新推文时,我所做的是:
- 检查数据库是否已经包含推文:如果是,我用新信息更新它(转推计数,如计数),否则我保存它
- 检查数据库是否已经包含用户:如果是,我用新信息更新它,否则我保存它
- 检查数据库是否已经包含主题标签:如果没有,我添加它
以此类推,保存关系的过程相同。
查询如下:
static String cqlAddTweet = "merge (n:Tweet{tweet_id: {2}}) on create set n.text={1}, n.location={3}, n.likecount={4}, n.retweetcount={5}, n.topic={6}, n.created_at={7} on match set n.likecount={4}, n.retweetcount={5}";
static String cqlAddHT = "merge (n:Hashtag{text:{1}})";
static String cqlHTToTweet = "match (n:Tweet),(m:Hashtag) where n.tweet_id={1} and m.text={2} merge (n)-[:TAGS]->(m)";
static String cqlAddUser = "merge (n:User{user_id:{3}}) on create set n.name={1}, n.username={2}, n.followers={4}, n.following={5}, n.profilePic={6} on match set n.name={1}, n.username={2}, n.followers={4}, n.following={5}, n.profilePic={6}";
static String cqlUserToTweet = "match (n:User),(m:Tweet) where m.tweet_id={2} and n.user_id={1} merge (n)-[:POSTS]->(m)";
static String cqlUserRetweets = "match (n:Tweet{tweet_id:{1}}), (u:User{user_id:{2}}) create (u)-[:RETWEETS]->(n)";
因为保存数据的速度很慢,我想如果我不运行所有那些每次都扫描数据的查询,这个系统会有更好的性能。
您对我的申请有什么建议吗?
谢谢你,如果这看起来很愚蠢,请提前原谅我。
确保在以下 label/property 对中有 indexes (or uniqueness constraints,如果合适)。这将使您的查询避免扫描具有相同标签的所有节点(在开始查询时)。
:Tweet(tweet_id)
:Hashtag(text)
:User(user_id)
顺便说一下,可以简化您的几个查询(但这应该不会影响性能):
static String cqlAddTweet = "MERGE (n:Tweet{tweet_id: {2}}) ON CREATE SET n.text={1}, n.location={3}, n.topic={6}, n.created_at={7} SET n.likecount={4}, n.retweetcount={5}";
static String cqlAddUser = "MERGE (n:User{user_id:{3}}) SET n.name={1}, n.username={2}, n.followers={4}, n.following={5}, n.profilePic={6}";