将新用户添加到neo4j

时间:2014-10-02 14:19:31

标签: graph neo4j cypher graph-databases

完全是neo4j noob在这里说话,

我喜欢创建一个图表来存储一组用户,典型的用户如下:

CREATE
(node_1 {FullName:"Peter Parker",FirstName:"peter",FamilyName:"parker"}),
(node_2 {Address:"Newyork",CountryCode:"US"}),
(node_3 {Location:"Hidden"}),
(node_4 {phoneNumber:11111}),
(node_5 {InternetEmailAddress:"peter@peterland.com")

现在的问题是,

  1. 每次执行此操作时,我都会添加5个节点。 我知道我需要使用一个唯一的密钥,但我看到的所有示例都可以使用唯一的密钥来表示特定节点。那么如果用户已经存在,我该如何确保用户不会被添加(我可以使用电子邮件地址作为唯一密钥)。
  2. 如果发生某些更改,如何更新节点。例如,一周之后我想更新图表以包含前一个而不是。(没有重复)

    CREATE(node_1 {FullName:"Peter Parker",FirstName:"peter",FamilyName:"parker"}),(node_2 {Address:"Newyork",CountryCode:"US"}),(node_3 {Location:"public"}),(node_4 {phoneNumber:11111}),(node_5 {InternetEmailAddress:"peter@peterland.com"),(node_6 {status:"Jailed"})
    
  3. (请注意,新更新将位置更改为“public”,并为 peter添加新节点

2 个答案:

答案 0 :(得分:2)

无论如何,看到你有很多节点。

你建模为节点的一些数据可能是属性,正如另一个答案所暗示的那样,有些可能正确建模为节点,有些可能形成 或部分关系。

位置public / hidden可以用以下三种方式之一建模:作为Person上的属性,作为Person和Location之间的属性或作为关系类型。首先要了解你需要建立关系。

目前您的地址是另一个节点,我认为这是正确的,但您可能需要两个节点,相关内容如下:

(s:State)-[:IN_COUNTRY]-(c:Country)

YMMV并且显然是以美国为中心的模型,但你可以足够宽松地扩展它。

现在你可以用LIVES_IN关系创建Peter:

CREATE (p:Person{fullName:"Peter Parker"}), (s:State{name:"New York"}), (c:Country{code:"US"}),
(p)-[:LIVES_IN]->(s), (s)-[:IN_COUNTRY]->(c)

为了提高速度,你最好建模两个关系,可能是LIVES_IN_PUBLIC和LIVES_IN_HIDDEN,这意味着要执行你想要的更新,然后你必须删除一个并创建另一个。但是,如果速度不重要,那么在关系中使用属性也很常见。

CREATE (p:Person{fullName:"Peter Parker"}), (s:State{name:"New York"}), (c:Country{code:"US"}),
(p)-[:LIVES_IN{public:false}]->(s), (s)-[:IN_COUNTRY]->(c)

所以你完整的Q& A:

CREATE (p:Person {fullName:"Peter Parker",firstName:"peter",familyName:"parker", phoneNumber:1111, internetEmailAddress:"peter@peterland.com"}),
(s:State {name:"New York"}), (c:Country {code:"US"}),
(p)-[:LIVES_IN{public:false}]->(s), (s)-[:IN_COUNTRY]-(c)

MATCH (p:Person {internetEmailAddress:"peter@peterland.com"})-[li:LIVES_IN]->()
SET li.public = true, p.status = "jailed"

添加其他人时,您可能不想重新创建状态和国家/地区,而是希望匹配它们,可能Merge,但我们会坚持创建。

MATCH (s:State{name:"New York"})
CREATE (p:Person{name:"John Smith", internetEmailAddress:"john@google.com"})-[:LIVES_IN{public:false}]->(s)
现在约翰史密斯也隐含地生活在美国,因为你可以通过州节点来关注这种关系。

论述完整。

答案 1 :(得分:0)

我认为你在这里错误地建模你的数据 - 你将这个人的每个属性设置为一个单独的节点,这不是一个好主意。您在这些节点之间没有任何链接,因此使用此数据模式,稍后您将无法分辨Peter Parker的地址。你也没有使用节点标签,我认为这可能对你有帮助。

关于更新节点的答案的快速问题是,您必须MATCH,然后使用SET修改属性。所以如果你有一个人,你可能会这样做:

MATCH (p:Person { FullName: "Peter Parker" })
SET p.Address = "123 Fake Street"
RETURN p;

但请注意,我对数据的结构方式做出了假设。我将采用您提供的相同数据,这可能是创建它的更好方法:

CREATE (node_1:Person {FullName:"Peter Parker",
                       FirstName:"peter",
                       FamilyName:"parker",
                       Address:"Newyork",CountryCode:"US",
                       Location:"Hidden",
                       phoneNumber:11111,
                       InternetEmailAddress:"peter@peterland.com"});

与此建议的不同之处在于,我将所有属性放入单个节点(而不是每个节点一个属性),并且我将Person标签应用于节点。

如果您构建了这样的数据,那么我提供的更新查询就可以了。像你拥有的那样构建数据,不可能更新Peter Parker的地址,因为你的node_1node_2

之间没有任何关系