【问题标题】:Cypher query return undesirable result密码查询返回不良结果
【发布时间】:2016-12-22 04:16:56
【问题描述】:

我需要获取文本并将它们保存到 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)

我只是找不到这里的问题。

谢谢!

【问题讨论】:

  • 你能描述一下这意味着支持什么样的操作吗?如果您希望实现快速文本搜索、查找和评分,那么已经设置了更好的工具来执行此操作,例如 ElasticSearch。
  • 谢谢!我看看这个
  • @InverseFalcon 我阅读了有关 ElasticSearch 的信息,但我发现这不是我想要的。谢谢,伙计!

标签: neo4j cypher py2neo


【解决方案1】:

我的解决办法是:

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)

【讨论】:

    【解决方案2】:

    好吧,您可能在这里遇到了数据建模问题。

    您在创建单词节点时使用 MERGE,因此如果该单词是从任何先前的文本查询中添加的,它将重用相同的节点,因此您更常见的单词节点(a、the、and、I 等) 可能会有很多 [:NEXT] 关系,这些关系会随着每次查询而继续增长。

    这是你的意思,还是你只会问你的数据库问题,关于只在查询中给定文本中使用的单词?

    编辑

    问题在于 :Word 节点的合并。这将匹配从任何先前查询创建的任何先前 :Word 节点,并将与任何未来查询匹配。合并 :Word 节点本身是不够的;要使您的单词仅对每个相关帖子本地化,您必须同时合并帖子中单词的关系。

    我们还可以清理用于计算单词分数的匹配模式,因为我们只需要每个单词的任意方向的 [: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)
    

    【讨论】:

    • 我只想要给定文本中使用的单词。非常感谢
    • 感谢您的澄清。我已经更新了我的答案。它应该将合并的单词保留在每个相关帖子的本地,并且应该简化分数计算。
    • 非常感谢@InverseFalcon。我现在有另一个任务,当我完成它时,我会回到这个。我稍后会测试它
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-31
    • 2019-09-18
    • 2012-05-08
    • 2016-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多