在 Neo4j 中将对象存储为 属性
Storing object as property in Neo4j
我需要在 Tile 节点中存储一组 User 对象。每个用户对象包含三个原始属性; Id(单个字母字符串)、fName 和 lName。此对象列表是 Tile 节点的 属性,具有其他几个基本属性。需要将整个 Tile 节点序列化为 Json,包括嵌套的 User 对象。
我了解 Neo 无法将复杂对象存储为属性。我将用户创建为一个单独的节点,并将 id、fName 和 lName 作为属性,我可以通过 Cypher 获取这些返回值。我还可以获得父 Tile 节点的 Json 输出结果。 (在这种情况下,Users 只是一串以逗号分隔的字母)。但是如何获得嵌套在父节点内的用户节点输出呢?
我通过 Cypher 查询将用户对象与 Tile 节点中的用户 ID 字符串相关联,从而创建了一个用户对象列表 (userList)。我只需要从两个单独的 json 输出到单个嵌套输出。
我希望这已经足够详细了。我正在使用 Neo4j 2.1.6 和 Neo4jClient。我也在使用.Net 4.0。
您不应将另一个对象存储为嵌套 属性。正如您正确指出的那样,neo4j 不支持它,但即使它支持,您也不应该这样做,因为您应该 link 两者有关系。这是像 neo4j 这样的图形数据库的关键优势,因此您应该发挥这种优势并使用关系。
服务器有一个默认的 JSON 格式,倾向于输出节点作为它们自己的 JSON 对象。这意味着实际上,由于您要将其建模为具有关系的两个独立节点,因此默认情况下您无法让服务器将一个对象的 JSON 嵌套在另一个对象的下面。它不会以这种方式嵌套 JSON,因为这不是存储数据的方式。
在这种情况下,我会使用 REST 服务分别为每个对象获取 JSON,然后自己在代码中进行嵌套——您的代码是您唯一可以嵌套的地方知道应该嵌套在哪个 属性 下,以及应该如何嵌套。
你可以用 cypher 做这样的事情,并让 cypher return 成为一个复合对象。
MATCH (t:Tile)-[:CONTAINS_USER]-(u:User)
WHERE t.name =~ 'Tile.*'
WITH {name: t.name, users: collect(u) } AS tile
RETURN collect(tile) AS tiles
除了这些答案之外,请注意,如果您不需要在任何查询中涉及子字段属性(例如,搜索 User.name 为 "X" 的 Tiles),您可以在插入之前简单地将对象字段序列化为字符串(例如使用JSON.stringify
),并在从数据库读取时反序列化它们。
当您想 "attach" 将结构化数据发送到节点时,这尤其有用,但您不太关心这些数据与数据库中的关系(例如用户偏好)。
我需要在 Tile 节点中存储一组 User 对象。每个用户对象包含三个原始属性; Id(单个字母字符串)、fName 和 lName。此对象列表是 Tile 节点的 属性,具有其他几个基本属性。需要将整个 Tile 节点序列化为 Json,包括嵌套的 User 对象。
我了解 Neo 无法将复杂对象存储为属性。我将用户创建为一个单独的节点,并将 id、fName 和 lName 作为属性,我可以通过 Cypher 获取这些返回值。我还可以获得父 Tile 节点的 Json 输出结果。 (在这种情况下,Users 只是一串以逗号分隔的字母)。但是如何获得嵌套在父节点内的用户节点输出呢?
我通过 Cypher 查询将用户对象与 Tile 节点中的用户 ID 字符串相关联,从而创建了一个用户对象列表 (userList)。我只需要从两个单独的 json 输出到单个嵌套输出。
我希望这已经足够详细了。我正在使用 Neo4j 2.1.6 和 Neo4jClient。我也在使用.Net 4.0。
您不应将另一个对象存储为嵌套 属性。正如您正确指出的那样,neo4j 不支持它,但即使它支持,您也不应该这样做,因为您应该 link 两者有关系。这是像 neo4j 这样的图形数据库的关键优势,因此您应该发挥这种优势并使用关系。
服务器有一个默认的 JSON 格式,倾向于输出节点作为它们自己的 JSON 对象。这意味着实际上,由于您要将其建模为具有关系的两个独立节点,因此默认情况下您无法让服务器将一个对象的 JSON 嵌套在另一个对象的下面。它不会以这种方式嵌套 JSON,因为这不是存储数据的方式。
在这种情况下,我会使用 REST 服务分别为每个对象获取 JSON,然后自己在代码中进行嵌套——您的代码是您唯一可以嵌套的地方知道应该嵌套在哪个 属性 下,以及应该如何嵌套。
你可以用 cypher 做这样的事情,并让 cypher return 成为一个复合对象。
MATCH (t:Tile)-[:CONTAINS_USER]-(u:User)
WHERE t.name =~ 'Tile.*'
WITH {name: t.name, users: collect(u) } AS tile
RETURN collect(tile) AS tiles
除了这些答案之外,请注意,如果您不需要在任何查询中涉及子字段属性(例如,搜索 User.name 为 "X" 的 Tiles),您可以在插入之前简单地将对象字段序列化为字符串(例如使用JSON.stringify
),并在从数据库读取时反序列化它们。
当您想 "attach" 将结构化数据发送到节点时,这尤其有用,但您不太关心这些数据与数据库中的关系(例如用户偏好)。