所以我的数据模型存在问题
我有艺术家,用户和标签
标签是我存储在节点中的唯一数据对象。
用户可以使用特定标签标记艺术家
我从以下关系开始
(user)-[:tags]->(tag)-[:on]->(artist)
当然,这无法识别标记艺术家的用户。
然后我想到尝试以下方法
(user)-[:tags]->(artist)->[:with]->(tag)
在这里,我可以识别艺术家,但无法确定艺术家的标签是什么。
我在这里有点失落。我知道我可以直接去
(user)-[:tags {tagname}]->artist
但是无论如何将标签表示为一个独立的实体,同时仍保持两端相关的数据
答案 0 :(得分:2)
您可以在tagId的帮助下标记艺术家以识别
(user)-[:tags {tagId}]->(artist)-[:with]->(tag {tagId})
答案 1 :(得分:2)
你想要hypergraph边缘连接2个以上的顶点(用户,标签,艺术家)。
但是,Neo4j不是超图实现,因此您需要引入一个表示“用户标记”的节点,并以规则的关系连接到3个节点:
MATCH (user:User {uuid: {userId}}),
(tag:Tag {uuid: {tagId}}),
(artist:Artist {uuid: {artistId}})
CREATE (user)-[:USER_TAGS]->(userTag:UserTag)-[:USES_TAG]->(tag),
(userTag)-[:TAGS_ARTIST]->(artist)
答案 2 :(得分:2)
一种选择是将其分解为两个独立的部分:应用于用户的标签(假设标签名称具有唯一约束),以及从标记器到标记的标记关系。不确定您的系统是否仅允许使用预定义标记,或者是否允许用户动态创建它们。
我们假设标签是预定义的:您拥有带有:标签标签的节点,您可以使用该标签上的查询生成用户可以使用的标签列表,或者用作用户类型的标签自动完成标签
所以说用户想要用标签标记艺术家。这将触发首先使用标记标记艺术家的操作,然后在用户和艺术家之间创建:标记关系。
MATCH (t:Tag {name:tagname}), (a:Artist {id:artistID}), (u:User {id:userID})
MERGE (t)<-[:taggedAs]-(a)
MERGE (user)-[:tags {tagname}]->(artist)
这种方法的优点在于,您可以保留两条信息(用户已使用特定标记标记了艺术家,并将艺术家标记为某些标记),以便您可以轻松查询这两种信息。信息:给定用户和艺术家,我们可以快速找出:标记它们之间的关系并获得带有这些名称的标签。我们还可以轻松查询所有用户对艺术家应用的标签,而无需迭代所有用户的每一个:标签关系。
缺点是用户删除标签是一个更复杂的操作,可能是竞争条件:必须删除用户和艺术家之间的标签关系,然后是其他所有:标记其他用户与该艺术家之间的关系需要检查以查看该标记是否仍适用于该用户,或者是否需要将其删除。您可能需要锁定此操作以防止竞争条件。如果不允许或很少删除用户的标签,那么这可能是一个可接受的解决方案。