3

我有一个应用程序在一个只有几千个节点/关系的小型数据库上的 Rails 应用程序中使用Neo4j.rb gem,我现在正在编写一个批量上传和下载脚本。主要用于备份/迁移目的。我现在有 2 个节点 - 条款和权限组。仅使用属性导出每个节点非常容易,但我缺少每个节点内的关联。有没有办法导出每个节点及其属性和关联?

仅具有 2 个彼此关联的节点的数据库示例:

# Create blank holding array
2.0.0-p353 :001 > bulk = []
 => []

# Iterate through each node and drop into array
2.0.0-p353 :002 > Term.all.each do |t|
2.0.0-p353 :003 >     bulk << t
2.0.0-p353 :004?>   end
 => [#<Term access_designation: nil, created_at: Mon, 20 Jul 2015 18:12:39 +0000, created_by: nil, data_availability: nil, definition: "New York", name: "Awesome Term", notes: nil, possible_values: nil, sensitivity_access_notes: nil, sensitivity_classification: nil, source_system: nil, updated_at: Mon, 20 Jul 2015 18:12:39 +0000, updated_by: nil>]
2.0.0-p353 :005 > PermissionGroup.all.each do |pg|
2.0.0-p353 :006 >     bulk << pg
2.0.0-p353 :007?>   end
 => [#<PermissionGroup created_at: Mon, 20 Jul 2015 18:14:29 +0000, created_by: nil, name: "my group", updated_at: Mon, 20 Jul 2015 18:14:29 +0000, updated_by: nil>]

# output result to json
2.0.0-p353 :008 > bulk.to_json
 => "[{\"term\":{\"name\":\"Awesome Term\",\"definition\":\"New York\",\"source_system\":null,\"possible_values\":null,\"notes\":null,\"data_availability\":null,\"sensitivity_classification\":null,\"access_designation\":null,\"sensitivity_access_notes\":null,\"created_at\":\"2015-07-20T18:12:39+00:00\",\"updated_at\":\"2015-07-20T18:12:39+00:00\",\"created_by\":null,\"updated_by\":null,\"id\":\"ed820017-24d9-4895-aea2-2a899c83987a\"}},{\"permission_group\":{\"name\":\"my group\",\"created_at\":\"2015-07-20T18:14:29+00:00\",\"updated_at\":\"2015-07-20T18:14:29+00:00\",\"created_by\":null,\"updated_by\":null,\"id\":\"7f6d87cf-a2d3-488e-be03-ca4087e48986\"}}]"

生成的 JSON 美化后如下所示:

[
    {
        "term": {
            "name": "Awesome Term",
            "definition": "New York",
            "source_system": null,
            "possible_values": null,
            "notes": null,
            "data_availability": null,
            "sensitivity_classification": null,
            "access_designation": null,
            "sensitivity_access_notes": null,
            "created_at": "2015-07-20T18:12:39+00:00",
            "updated_at": "2015-07-20T18:12:39+00:00",
            "created_by": null,
            "updated_by": null,
            "id": "ed820017-24d9-4895-aea2-2a899c83987a"
        }
    },
    {
        "permission_group": {
            "name": "my group",
            "created_at": "2015-07-20T18:14:29+00:00",
            "updated_at": "2015-07-20T18:14:29+00:00",
            "created_by": null,
            "updated_by": null,
            "id": "7f6d87cf-a2d3-488e-be03-ca4087e48986"
        }
    }
]

但它缺少关联。我知道当我查询时我有它们

2.0.0-p353 :010 > t = Term.first
 => #<Term access_designation: nil, created_at: Mon, 20 Jul 2015 18:12:39 +0000, created_by: nil, data_availability: nil, definition: "New York", name: "Awesome Term", notes: nil, possible_values: nil, sensitivity_access_notes: nil, sensitivity_classification: nil, source_system: nil, updated_at: Mon, 20 Jul 2015 18:12:39 +0000, updated_by: nil>
2.0.0-p353 :011 > t.permission_group
 => #<PermissionGroup created_at: Mon, 20 Jul 2015 18:14:29 +0000, created_by: nil, name: "my group", updated_at: Mon, 20 Jul 2015 18:14:29 +0000, updated_by: nil>
2.0.0-p353 :012 > t.permission_group.name
 => "my group"

所以我的问题是如何输出所有节点及其属性和关联?有没有花哨的 neo4j.rb 魔术方法,还是我必须手动写出密码查询?

4

2 回答 2

2

这是一个很好的问题。您刚刚提醒我,我想创建方法来获取关联的 ID。我只是将一些工作代码放在一起,这些代码将进入 master(仍然需要测试),它提供以下内容:

t.permission_group_id # UUID
t.permission_group_neo_id # Neo4j ID

pg.term_ids
pg.term_neo_ids

显然,这不会是一丁点。此外,to_jsonforActiveNode需要更改以在 JSON 中输出这些 ID(可能基于一个选项)。还有要考虑的 ActiveRel 模型。

话虽如此,我不确定这是进行备份的最佳方式。问题是,如果你去恢复,你会在关系的双方都有模型试图创建这种关系,这意味着你最终会得到两个关系。你可以做一个MERGE,但有时你也想要两个关系;)

所以我建议使用内置的 Neo4j 备份工具。有neo4j-backup工具:

http://neo4j.com/docs/stable/re04.html

虽然我认为这可能只在企业中(我没有在我的社区安装中看到它)。

还有dump来自 Cypher 的命令:

http://neo4j.com/docs/stable/shell-commands.html#_dumping_the_database_or_cypher_statement_results

我在文档中指出的是一个实验性功能。

这能解决你的问题吗?如果没有,我可以研究其他解决方案;)

于 2015-07-21T15:12:39.090 回答
2

我仍然认为直接通过 Neo4j 备份是最好的。既然您说您的数据库不是很大,您应该能够执行一些简单的 Cypher 查询,如下所示:

MATCH n RETURN n

MATCH (a)-[r]->(b) RETURN a, r, b

根据您获得的信息,r您可以执行以下操作:

MATCH ()-[r]->() RETURN r

在 Neo4j.rb 中,您可以像这样运行 Cypher 查询:

Neo4j::Session.current.query('MATCH n RETURN n')

或像这样:

Neo4j::Session.current.query.match(:n).pluck(:n)
于 2015-07-21T15:24:39.893 回答