【问题标题】:neo4j load csv - some part doesnt workneo4j 加载 csv - 某些部分不起作用
【发布时间】:2015-05-18 16:56:15
【问题描述】:

我在从 csv 导入时遇到问题。

我在 shell 中运行以下内容,而最后一部分 (MERGE (e1)-[:NEXT]->(hit)))) 从未发生过。 有点郁闷……

每个会话都有 x 次点击。 我想找到插入会话的最后一次命中,并通过 NEXT 关系将其与新命中连接

PSV 样本:

Session_id|日期时间 xxx|2015-01-01T01:00:00 xxx|2015-02-02T09:00:00 年年|2015-03-03T06:00:44

代码:

USING PERIODIC COMMIT 100
 LOAD CSV WITH HEADERS FROM 'file:///home/xxx.csv' AS line FIELDTERMINATOR '|'


 MERGE (session :Session { session_id:line.session_id })
 MERGE (hit:Hit{date:line.date_time})

//........更多合并......

//关系

CREATE (hit)-[:IN_SESSION]->(session) 
 CREATE ....//more relations

 WITH session

 MATCH (prev_hit:Hit)-[:IN_SESSION]->(session)
 WITH prev_hit ORDER BY prev_hit.date_time DESC LIMIT 2
 WITH collect(prev_hit) as entries

 FOREACH(i in RANGE(0, length(entries)-1) | 
   FOREACH(e1 in [entries[i]] | 
        MERGE (e1)-[:NEXT]->(hit)))

【问题讨论】:

  • 您在 CREATE 语句中缺少 :Hit 标签
  • 对不起,我只是没有把它贴在这里。这是“合并...”的地方
  • 然后请粘贴您的完整加载 csv,以便我们更好地帮助您
  • 感谢 Christophe,我在回家的路上用手机编辑了这个问题……如果这还不够好,我稍后会发布完整的代码。
  • 您的意思是脚本完成但MERGE 从未运行,还是脚本挂起?你用的是什么版本的 Neo4j?

标签: neo4j cypher load-csv


【解决方案1】:

我看不出你想用嵌套的FOREACH 循环实现什么。

如果你真的得到了hit 节点和session 节点,一个简单的MERGE 应该没问题。我认为您必须在 WITH 声明中包含 hit

MERGE (session :Session { id: "xxx" })
MERGE (hit:Hit { date_time:"2015-04-03T06:00:44" })
CREATE (hit)-[:IN_SESSION]->(session)
WITH session, hit
MATCH (prev_hit:Hit)-[:IN_SESSION]->(session)
WHERE prev_hit <> hit // make sure that you only match other hits
WITH hit, prev_hit 
ORDER BY prev_hit.date_time DESC LIMIT 1
MERGE (prev_hit)-[:NEXT]->(hit) // create relationship between the two 

更新

我更新了查询以仅匹配不是当前命中的prev_hit。上面的查询可以按您的意愿工作,即它创建了一个与单个 Hit 节点相关的单个 NEXT 关系,该节点与同一 Session 相关。见这里:http://console.neo4j.org/?id=ov7mer

date_time 可能存在问题。我认为您将其存储为字符串,排序可能并不总是给您预期的结果。

更新 2

关于您的第二条评论:如果您逐行检查文件并添加Hit 节点,则只能将关系添加到已添加的Hit 节点。如果您想要Hit 节点之间的NEXT 关系的连续链,您只能在一个查询中执行此操作,前提是您确保 CSV 文件的条目按 date_time 升序排列。

您可以稍后在Hit 节点之间添加NEXT 关系,如下所述:http://www.markhneedham.com/blog/2014/04/19/neo4j-cypher-creating-relationships-between-a-collection-of-nodes-invalid-input/

开始查询:

MATCH (s:Session)--(hit:Hit)
// first order by hit.date_time
WITH DISTINCT s, hit ORDER BY hit.date_time DESC
// this will return one row per session with the hits in a collection
WITH s, collect(hit) AS this_session_hits
// try this to check the ordering:
// RETURN s.session_id, this_session_hits

// the following queries will be done on each row, this is like iterating over the sessions
FOREACH(i in RANGE(0, length(this_session_hits)-2) | 
    FOREACH(e1 in [this_session_hits[i]] |
        FOREACH(e2 in [this_session_hits[i+1]] |
            MERGE (e1)-[:NEXT]->(e2))))

最终答案 ;)

此查询适用于 neo4j 控制台 (http://console.neo4j.org/?id=mginka) 中的数据集。它将会话中的所有HitNEXT 关系连接起来。

MATCH (s:Session)<--(hit:Hit)
WITH DISTINCT s, hit
ORDER BY hit.date_time ASC 
WITH s, collect(hit) AS this_session_hits
FOREACH (i IN RANGE(0, length(this_session_hits)-2)| 
    FOREACH (e1 IN [this_session_hits[i]]| 
        FOREACH (e2 IN [this_session_hits[i+1]]| 
            MERGE (e1)-[:NEXT]->(e2))))

【讨论】:

  • 以下代码可以工作,但会为所有点击创建关系——即使来自不同的会话。我如何迭代所有会话,然后从同一个会话中迭代所有点击? WITH hit ORDER BY hit.date_time DESC&lt;br/&gt; WITH collect(hit) as entries &lt;br/&gt; FOREACH(i in RANGE(0, length(entries)-2) | FOREACH(e1 in [entries[i]] | FOREACH(e2 in [entries[i+1]] | MERGE (e1)-[:NEXT]-&gt;(e2))))
  • 感谢@Martin-preusse 这在第一次和最后一次命中之间创建了一个关系(更改为限制 1)。我想在第一击与第二击之间、第二击与第三击之间建立关系,依此类推。任何帮助将不胜感激。
  • 非常感谢@Martin。查询看起来很完美,但是您已经使用 {id='xxx'} 开始了它。我想要的是获取所有会话 > 迭代它们,然后使用每次迭代的会话 id 运行查询:'xxx' 的所有命中 -> 然后'xxx1' 的所有命中等等再次感谢
  • 看看MATCH (s:Session)--(hit:Hit)返回什么。你用他们的命中迭代所有会话。
  • 非常感谢,抱歉打扰了,但我上周第一次安装了 neo4j。你能加倍努力,并提出完整的查询(假设加载已经完成,那是一个不同的脚本,所以不需要添加他和会话之间的第一个关系 - 只在命中之间)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-09
  • 1970-01-01
  • 2022-07-20
  • 2011-11-17
  • 2021-04-24
  • 2011-02-20
  • 1970-01-01
相关资源
最近更新 更多