【问题标题】:How to get-or-create a unique child node in Neo4j如何在 Neo4j 中获取或创建唯一的子节点
【发布时间】:2016-08-16 05:01:40
【问题描述】:

我是 Neo4j 的新手,正在尝试建立一个音乐数据库。首先,我只是在玩两个标签:

  • Artist
  • Song

显然这是一种父子关系,其中SongArtist(或可能是多个Artists)的子关系,可能类似于:

(:Artist {name:'name'})-[:RECORDED]->(:Song {title:'title'})

我做出以下假设:

  • 艺术家的名字是独一无二的
  • 歌曲标题不是唯一的
  • 重复摄取数据是不可避免的

举一个我想做的例子:

  1. 我收录了 Leonard Cohen 的“哈利路亚”。创建了一个新的Artist 节点和Song 节点,具有RECORDED 关系
  2. 我收录了 Jeff Buckley 的“哈利路亚”。同样,新的ArtistSong 节点被创建,具有RECORDED 关系。第一个“哈利路亚”Song 根本与这个新图无关。
  3. 我再次收录了 Jeff Buckley 的“哈利路亚”。什么都没有发生。
  4. 我摄取了 Jeff Buckley 的“丁香酒”。我们重用了旧的Artist 节点,但我有一个新的Song 节点与RECORDED 关系

据我所知,使用MERGE 让我很接近,但不是很接近(它停止了ARTIST 的重复,但不是SONG 的重复)。如果我使用CREATE,则第 3 点无法正常工作。

我想我可以在SONG 标签中添加另一个属性来跟踪它的ARTIST(因此我可以使其独一无二),但这对于图形数据库来说似乎有点多余和单一,不是吗?

对于执行这些关系和要求的最简洁方式,有人有什么好主意吗?

【问题讨论】:

    标签: neo4j


    【解决方案1】:

    先合并艺术家,再合并歌曲:

    WITH 'Leonard Cohen' AS ArtistName, 
         'Hallelujah'    AS SongTitle
    MERGE (A:Artist {name:ArtistName})
    WITH A, 
         SongTitle 
    OPTIONAL MATCH p=(A)-[:RECORDED]->(:Song {title:SongTitle})
    FOREACH (x in CASE WHEN p IS NULL THEN [1] ELSE [] END |
      CREATE (S:Song {title:SongTitle})
      MERGE (A)-[:RECORDED]->(S)
    ) 
    WITH A, 
         SongTitle
    MATCH p = (A)-[:RECORDED]->(:Song {title:SongTitle})
    RETURN p
    

    【讨论】:

    • 这确实有效,尽管现在已经看到实现这一点需要多么复杂的语法,我倾向于在我的 artists 上使用多余的 artist 属性,这样我可以写MERGE (a)-[:RECORDED]->(s:Song {title:'Hallelujah',artist:'Leonard Cohen'}) 之类的东西(或者甚至可以完全取消Artist 标签?!)
    【解决方案2】:

    我不认为歌曲标题是你可以依赖的唯一性,特别是如果这个图表包括现有歌曲的封面。

    确定一些额外的手段来暗示独特性是要走的路。

    艺术家是一种方式。记录日期可能是要考虑的另一条数据。如果您是从其他类型的数据库中读取此信息,则它们可能会使用其他一些唯一 ID 来实现唯一性。

    无论如何,一旦您有了要用于确定唯一性的字段,请将您的歌曲节点与所有这些字段合并。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-04-28
      • 1970-01-01
      • 1970-01-01
      • 2013-08-24
      • 1970-01-01
      • 1970-01-01
      • 2016-10-27
      相关资源
      最近更新 更多