1

我是 Neo4j 的新手,目前我正在尝试将交友网站制作为 POC。我有 4GB 的输入文件,看起来像下面的格式。

这包含 viewerId(male/female),viewedId 是他们查看过的 id 列表。根据这个历史文件,当任何用户上线时,我需要给出推荐。

输入文件:

viewerId   viewedId 
12345   123456,23456,987653 
23456   23456,123456,234567 
34567   234567,765678,987653 
:

对于这个任务,我尝试了以下方式,

USING PERIODIC COMMIT 10000
LOAD CSV WITH HEADERS FROM "file:/home/hadoopuser/Neo-input " AS row
FIELDTERMINATOR '\t'
WITH row, split(row.viewedId, ",") AS viewedIds
UNWIND viewedIds AS viewedId
MERGE (p2:Persons2 {viewerId: row.viewerId})
MERGE (c2:Companies2 {viewedId: viewedId})
MERGE (p2)-[:Friends]->(c2)
MERGE (c2)-[:Sees]->(p2);

而我的 Cypher 查询来获得结果是,

MATCH (p2:Persons2)-[r*1..3]->(c2: Companies2)
RETURN p2,r, COLLECT(DISTINCT c2) as friends 

要完成这项任务,需要 3 天时间。

我的系统配置:

Ubuntu -14.04  
RAM -24GB

Neo4j 配置:
neo4j.properties:

neostore.nodestore.db.mapped_memory=200M
neostore.propertystore.db.mapped_memory=2300M
neostore.propertystore.db.arrays.mapped_memory=5M
neostore.propertystore.db.strings.mapped_memory=3200M
neostore.relationshipstore.db.mapped_memory=800M

neo4j-wrapper.conf

wrapper.java.initmemory=12000
wrapper.java.maxmemory=12000

为了减少时间,我从以下链接 https://github.com/jexp/batch-import在互联网上搜索并获得一个想法,例如 Batch importer

在那个链接中,他们有 node.csv、rels.csv 文件,它们导入到 Neo4j 中。我不知道他们如何创建 node.csv 和 rels.csv 文件,他们正在使用哪些脚本以及所有这些文件。

谁能给我示例脚本来为我的数据制作 node.csv 和 rels.csv 文件?

或者您能提供任何建议以加快导入和检索数据的速度吗?

提前致谢。

4

1 回答 1

1

你不需要反向关系,只有一个就足够了!

对于导入,将堆 (neo4j-wrapper.conf) 配置为 12G,将页面缓存 (neo4j.properties) 配置为 10G。

试试这个,它应该在几分钟内完成。

create constraint on (p:Persons2) assert p.viewerId is unique;
create constraint on (p:Companies2) assert p.viewedId is unique;

USING PERIODIC COMMIT 10000
LOAD CSV WITH HEADERS FROM "file:/home/hadoopuser/Neo-input " AS row
FIELDTERMINATOR '\t'
MERGE (p2:Persons2 {viewerId: row.viewerId});

USING PERIODIC COMMIT 10000
LOAD CSV WITH HEADERS FROM "file:/home/hadoopuser/Neo-input " AS row
FIELDTERMINATOR '\t'
FOREACH (viewedId IN split(row.viewedId, ",") |
  MERGE (c2:Companies2 {viewedId: viewedId}));

USING PERIODIC COMMIT 10000
LOAD CSV WITH HEADERS FROM "file:/home/hadoopuser/Neo-input " AS row
FIELDTERMINATOR '\t'
WITH row, split(row.viewedId, ",") AS viewedIds
MATCH (p2:Persons2 {viewerId: row.viewerId})
UNWIND viewedIds AS viewedId
MATCH (c2:Companies2 {viewedId: viewedId})
MERGE (p2)-[:Friends]->(c2);

对于关系合并,如果您有一些拥有数十万到数百万视图的公司,您可能希望使用它来代替:

USING PERIODIC COMMIT 10000
LOAD CSV WITH HEADERS FROM "file:/home/hadoopuser/Neo-input " AS row
FIELDTERMINATOR '\t'
WITH row, split(row.viewedId, ",") AS viewedIds
MATCH (p2:Persons2 {viewerId: row.viewerId})
UNWIND viewedIds AS viewedId
MATCH (c2:Companies2 {viewedId: viewedId})
WHERE shortestPath((p2)-[:Friends]->(c2)) IS NULL
CREATE (p2)-[:Friends]->(c2);

关于您的查询?

你想通过检索所有人和所有公司之间的交叉产品达到 3 层深度来实现什么?这些可能是数万亿条路径?

通常你想为一个人或一个公司知道这一点

更新您的查询

例如。对于123456,所有浏览过这家公司的人是12345,23456,那么这些人浏览过哪些公司12345 123456,23456,987653 23456 23456,123456,234567 那么我需要推荐公司-123456为23456,987653, 23456,234567 结果不同(最终结果) 23456,987653,234567

match (c:Companies2)<-[:Friends]-(p1:Persons2)-[:Friends]->(c2:Companies2)
where c.viewedId = 123456
return distinct c2.viewedId;

对于所有公司,这可能会有所帮助:

match (c:Companies2)<-[:Friends]-(p1:Persons2)
with p1, collect(c) as companies
match (p1)-[:Friends]->(c2:Companies2)
return c2.viewedId, extract(c in companies | c.viewedId);
于 2015-06-23T11:59:34.690 回答