【问题标题】:Conditional query in neo4j using apoc使用 apoc 在 Neo4j 中进行条件查询
【发布时间】:2017-12-21 09:41:04
【问题描述】:

我正在尝试在密码中执行条件查询下面是我的示例查询,但即使条件为真,它也不会创建新的对话节点。

WITH ["Ram", "Shyam", "Hari"] as names
WITH names, size(names) AS requiredCount
MATCH (u:User) WHERE u.name IN names
WITH u, requiredCount
MATCH (u)-[:IS_PARTICIPANT]->(c:Conversation)
WITH requiredCount, c, u, count(u) as matches
WHERE requiredCount = matches and size(()-[:IS_PARTICIPANT]->(c)) = requiredCount
WITH u, count(c) as conversationExists
CALL apoc.do.when(conversationExists < 1, 'MERGE (cc:Conversation {_id: 
 apoc.create.uuid(), createdAt: timestamp()}) RETURN cc', '', {u: u}) YIELD value
RETURN value

【问题讨论】:

    标签: neo4j cypher neo4j-apoc


    【解决方案1】:

    这里有几件事。

    names 应该出现在第二行的 WITH 中(我认为您将其重命名为 userIDs 是错误的)。

    你有WITH requiredCount, c, u, count(u) as matches,它并没有按照你的想法做。聚合函数具有来自非聚合列(形成分组键)的上下文。像这样读出它会有所帮助:“对于每个 requiredCount、c 和 u,给我那个 u 的计数”。每行只有 1 个 u,因此每行的 matches 计数始终为 1,因此只要名称集合大于 1,您的查询将始终失败。您可以通过将 WITH 更改为 RETURN 来自行测试该行,并注释掉其余部分。你将不得不以不同的方式处理这个问题,要么收集u,要么将其从该行中删除。

    您还必须小心执行与某些内容不匹配的 MATCH 或在评估为 false 的 WITH 子句上使用 WHERE 子句,因为如果这会清除所有行,您将无法继续查询(基本上如果您的 MATCH 和 WHERE 失败,您将根本无法到达这条线:WITH u, count(c) as conversationExists)。您可以尝试使用 OPTIONAL MATCH,或者将 WHERE 子句提取为 WITH 子句中的布尔变量。

    【讨论】:

    • 最后我明白了 WITH 和 WHERE 的使用,一个问题虽然如果我使用 WITH (userCnt = inputCnt AND size(()-[:IS_PARTICIPANT]-&gt;(c)) = inputCnt) as check 这将通过用户的所有对话,对吗?我猜这会很昂贵,所以我只进行了两个查询。第一个检查用户之间是否存在对话,如果不存在则创建新的对话节点。
    • 那个 WITH 子句只会遍历给定用户(不是所有用户)的所有对话,以及 size() check is efficient;它从对话节点获取 :IS_PARTICIPANT 关系的程度,而无需实际扩展关系。
    • 我担心使用 WHERE 或 WITH,如果我使用 WHERE 或 WITH,查询成本是否相同?
    • 我只是用 PROFILE 来检查,似乎是类似的 db hits。我将尝试使用单个查询来检查和创建一次对话并查看差异。谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多