Cypher 查询 return 不良结果
Cypher query return undesirable result
我需要获取文本并将它们保存到 Neo4j。之后,我将该文本的每个单词分开,并在它们之间创建一个 [:NEXT] 关系,指示另一个单词之后的单词,并创建一个 [:CONTAINS] 关系,指示该文本包含该单词。
最后,我尝试在文本中找到具有更多关系 [:NEXT] 但不是在整个数据库中的单词。仅在给定的文本中。
不幸的是,我只得到了整个数据库的总和。
查询是:
query = '''
WITH split("%s"," ") as words
MERGE (p:Post {id: '%s', text: '%s'})
WITH p, words
UNWIND range(0,size(words)-2) as idx
MERGE (w1:Word {name:words[idx]})
MERGE (w2:Word {name:words[idx+1]})
MERGE (w1)-[:NEXT]->(w2)
MERGE (p)-[:CONTAINS]->(w2)
MERGE (p)-[:CONTAINS]->(w1)
WITH p
MATCH (p)-[c:CONTAINS]->(w:Word)
MATCH ()-[n1:NEXT]->(:Word {name: w.name})<-[:CONTAINS]-(p)
MATCH (p)-[:CONTAINS]-(:Word {name: w.name})-[n2:NEXT]->()
WITH COUNT(n1) + COUNT(n2)AS score, w.name AS word, p.text AS post, p.id AS _id
RETURN post, word, score, _id;
''' %(text, id, text)
我只是找不到这里的问题。
谢谢!
嗯,您可能遇到了数据建模问题。
您在创建单词节点时正在使用 MERGE,因此如果该单词是从任何先前的文本查询中添加的,它将重复使用同一节点,因此您更常用的单词节点(a、the 和 I等) 可能会有许多 [:NEXT] 关系,这些关系将随着每个查询而继续增长。
这就是您的意思,还是您只询问数据库有关查询中仅给定文本中使用的词的问题?
编辑
问题是 :Word 节点的合并。这将匹配任何先前的 :Word 节点,该节点是从任何先前的查询创建的,并将与任何未来的查询匹配。合并 :Word 节点本身是不够的;要使您的单词仅对每个关联的 post 本地化,您必须同时合并 post 中单词的关系。
我们还可以清理用于匹配的模式来计算单词得分,因为我们只需要每个单词任何方向的 [:NEXT] 关系的数量。
query = '''
WITH split("%s"," ") as words
MERGE (p:Post {id: '%s', text: '%s'})
WITH p, words
UNWIND range(0,size(words)-2) as idx
MERGE (p)-[:CONTAINS]->(w1:Word {name:words[idx]})
MERGE (p)-[:CONTAINS]->(w2:Word {name:words[idx+1]})
MERGE (w1)-[:NEXT]->(w2)
WITH p
MATCH (p)-[:CONTAINS]->(w:Word)
WITH size( ()-[:NEXT]-(w) ) AS score, w.name AS word, p.text AS post, p.id AS _id
RETURN post, word, score, _id;
''' %(text, id, text)
我的解决方案是:
query = '''
WITH split("%s"," ") AS words
MERGE (p:Post {id: "%s", text:"%s"})
WITH p, words
UNWIND range(0,size(words)-2) as idx
MERGE (w1:Word {name:words[idx]})
MERGE (w2:Word {name:words[idx+1]})
MERGE (w1)-[n:NEXT]->(w2)
ON MATCH SET n.count = n.count + 1
ON CREATE SET n.count = 1
MERGE (p)-[:CONTAINS]->(w2)
MERGE (p)-[:CONTAINS]->(w1)
''' %(text, id, text)
我需要获取文本并将它们保存到 Neo4j。之后,我将该文本的每个单词分开,并在它们之间创建一个 [:NEXT] 关系,指示另一个单词之后的单词,并创建一个 [:CONTAINS] 关系,指示该文本包含该单词。 最后,我尝试在文本中找到具有更多关系 [:NEXT] 但不是在整个数据库中的单词。仅在给定的文本中。
不幸的是,我只得到了整个数据库的总和。
查询是:
query = '''
WITH split("%s"," ") as words
MERGE (p:Post {id: '%s', text: '%s'})
WITH p, words
UNWIND range(0,size(words)-2) as idx
MERGE (w1:Word {name:words[idx]})
MERGE (w2:Word {name:words[idx+1]})
MERGE (w1)-[:NEXT]->(w2)
MERGE (p)-[:CONTAINS]->(w2)
MERGE (p)-[:CONTAINS]->(w1)
WITH p
MATCH (p)-[c:CONTAINS]->(w:Word)
MATCH ()-[n1:NEXT]->(:Word {name: w.name})<-[:CONTAINS]-(p)
MATCH (p)-[:CONTAINS]-(:Word {name: w.name})-[n2:NEXT]->()
WITH COUNT(n1) + COUNT(n2)AS score, w.name AS word, p.text AS post, p.id AS _id
RETURN post, word, score, _id;
''' %(text, id, text)
我只是找不到这里的问题。
谢谢!
嗯,您可能遇到了数据建模问题。
您在创建单词节点时正在使用 MERGE,因此如果该单词是从任何先前的文本查询中添加的,它将重复使用同一节点,因此您更常用的单词节点(a、the 和 I等) 可能会有许多 [:NEXT] 关系,这些关系将随着每个查询而继续增长。
这就是您的意思,还是您只询问数据库有关查询中仅给定文本中使用的词的问题?
编辑
问题是 :Word 节点的合并。这将匹配任何先前的 :Word 节点,该节点是从任何先前的查询创建的,并将与任何未来的查询匹配。合并 :Word 节点本身是不够的;要使您的单词仅对每个关联的 post 本地化,您必须同时合并 post 中单词的关系。
我们还可以清理用于匹配的模式来计算单词得分,因为我们只需要每个单词任何方向的 [:NEXT] 关系的数量。
query = '''
WITH split("%s"," ") as words
MERGE (p:Post {id: '%s', text: '%s'})
WITH p, words
UNWIND range(0,size(words)-2) as idx
MERGE (p)-[:CONTAINS]->(w1:Word {name:words[idx]})
MERGE (p)-[:CONTAINS]->(w2:Word {name:words[idx+1]})
MERGE (w1)-[:NEXT]->(w2)
WITH p
MATCH (p)-[:CONTAINS]->(w:Word)
WITH size( ()-[:NEXT]-(w) ) AS score, w.name AS word, p.text AS post, p.id AS _id
RETURN post, word, score, _id;
''' %(text, id, text)
我的解决方案是:
query = '''
WITH split("%s"," ") AS words
MERGE (p:Post {id: "%s", text:"%s"})
WITH p, words
UNWIND range(0,size(words)-2) as idx
MERGE (w1:Word {name:words[idx]})
MERGE (w2:Word {name:words[idx+1]})
MERGE (w1)-[n:NEXT]->(w2)
ON MATCH SET n.count = n.count + 1
ON CREATE SET n.count = 1
MERGE (p)-[:CONTAINS]->(w2)
MERGE (p)-[:CONTAINS]->(w1)
''' %(text, id, text)