【问题标题】:Neo4j node and relationship structureNeo4j 节点和关系结构
【发布时间】:2014-10-01 13:40:03
【问题描述】:

在 Neo4j 中,我有一个人节点、公司节点和职位节点。因此,“人”在“公司”中具有“职位”。我有一个关于建模数据库和这些节点之间的关系的问题。

我可以这样设置(密码“伪代码”):

(person)-[:WORKS_AT]-(company) 
(person)-[:HAS_TITLE]->(position) 
(company)-[:HAS_POSITION]->(position)

人有关系HAS_TITLE和WORKS_AT,或者像这样:

(person)-[:HAS_TITLE]->(position)<-[:HAS_POSITION]-(company)

人与公司没有直接关系的地方,我就得通过职位节点找到公司。

我想这在一定程度上取决于我想从数据库中得到什么,但是在图形数据库中是否有“正确/标准”的方式来做到这一点?

编辑:

在数据库中搜索时,我想获取一个人的所有职位。我想将它们作为这样的集合返回:

    [
      { 
        company: 'some company', 
        position: 'some position at the company' 
      }, 
      { 
        company: 'some other company', 
        position: '' // empty position, I dont have the position data here 
      } ,     
      { 
        company: 'some other company', 
        position: 'some position at the company'
      }      
    ] 

编辑 2:

澄清一下:这是我要使用的数据结构(json)。这只是一个人的数据,有多个人可以在不同的公司担任相同的职位等。我需要将其放入 Neo4j 并使其可搜索:

  {   
     "id": 123,
     "name": "Foo Bar",
     "email": "",
     "workhistory": {
        "positions": [
           {
              "company": "Company A",
              "employees": "",
              "type": "Privately Held",
              "start": 1356998400,
              "end": "",
              "position": "Position A",
              "description": "",
              "industry": "some industry"
           },
           {
              "company": "Company B",
              "employees": "",
              "type": "Privately Held",
              "start": 1356998400,
              "end": "",
              "position": "Position B",
              "description": "",
              "industry": "some industry"
           },
           {
              "company": "Company C",
              "employees": "",
              "type": "Privately Held",
              "start": 1341100800,
              "end": "",
              "position": "Position A",
              "description": "",
              "industry": ""
           }
        ]
     }
  }

我希望能够搜索具有名为“职位 A”的“名称”属性的“职位”节点,然后找到所有具有该职位的人,并以与放置时相同的结构返回他们的个人资料进入数据库,给予或接受。

“行业”和“公司”也是如此,我也想将它们分成单独的节点。该数据库将包含数百万人。

编辑 3

我正在考虑可能将职位添加为节点,具有“名称”属性等。然后还将职位名称添加到从个人到公司的关系中。这将使查询工作历史变得容易,但会为每个 WORKED_AT 关系(WORKED_AT.position 属性)占用额外的空间。使用这种结构,我也可以在位置节点上进行搜索,并获取与某个位置相关的所有人员。

这对于这个简单的结构来说可能没问题,但是更多的“嵌套”值呢?喜欢人住在位于国家/地区等州的城市吗?

【问题讨论】:

  • 这在很大程度上取决于你想从数据库中得到什么。 FWIW,你在这里的设计对我来说看起来完全合理。你能详细说明你的问题吗?如果您通过职位将人和公司联系起来,那看起来可能是可行的。您担心无法使用此设计做什么?
  • 我担心我最终可能会遇到一个我没有职位数据的人,所以不会有连接这个人和公司的节点,即使他确实在那里工作,我只是不知道他在那里做了什么。我需要将位置作为节点的原因是我想用标签对其进行索引并能够对其进行搜索。我可以将职位作为财产放在人和公司之间的关系上,但是我将无法搜索它,而不会受到影响。
  • 如果你一直都知道这个人工作的公司,那么即使你错过了他们的职位,你也可以通过 :WORKS_AT 链接他们。您还可以创建一个虚拟职位“未知”(每个公司一个),然后如果您知道该人为 X 公司工作但不知道他们的头衔,则将该人链接到该职位。这样,即使您不知道值应该是什么,链接也始终存在。
  • 如果你总是知道一个人在哪家公司工作,那么你很可能被搞砸了。如果信息不在您的数据集中,那么图形设计将无济于事,因为您只是不知道。 :)
  • 我一直都知道一个人在哪个公司工作,我想 :) 所以,如果有职位,创建 WORKS_FOR,如果没有职位,不创建 WORKS_FOR,只创建 HAS_TITLE?编辑了问题以显示我想从数据库中获取什么。

标签: database-design neo4j graph-databases


【解决方案1】:

在这种情况下,我认为“正确”的做法是让您的数据和应用感觉最自然的方式。就性能而言,遍历两种关系而不是一种关系来查找公司不会产生任何额外的影响,除非一个职位被如此多的公司共享,以至于有强烈的逻辑来确定哪一个与该用户相关联。

但决定因素应该是您是否拥有个人与公司关系独有的数据。我首先想到的是hired_on 属性来跟踪一个人在那里呆了多长时间。您可能希望独立于该人的职位来查看这一点——我会在人和职位之间放置一个started_on 属性——但您不想要一个人的工作经历吗?诸如工资、电话分机、办公室号码之类的东西……它们都可以进入那种关系的属性中。您不会将它们放在HAS_TITLE 关系上,因为如果标题更改,您将失去这些。它们也可以是person 上的资产,但人们不能为多家公司工作吗?

【讨论】:

  • 是的,我确实有关于关系的属性,比如开始和结束日期。即使对于人与职位、人与公司之间的关系,它们也可能是相同的。一个人可以在同一家或不同的公司担任多个职位,包括当前和过去的多个职位。一个职位可能会与很多公司相关联。做查询时,我一般先匹配person节点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-08-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-08
相关资源
最近更新 更多