简体   繁体   中英

How to “combine” two nodes and relationships in neo4j using Cypher

I'm modeling a "tag cloud" with the graph:

(t:Tag {name:'cypher'})-[:IN]->(g:TagGroup)<-[:TAGGED]-(x)

IE: A named tag is part of a "TagGroup", to which zero or more nodes are "TAGGED". I chose this design as I want the ability to combine two or more named tags (eg "cypher" and "neo4j") so that both (Tag) s are [IN] the new (TagGroup) and the new (TagGroup) is the endpoint for the union of all nodes that were previously [TAGGED] .

My only (not very pleasing) attempt is:

match (t:Tag {name:'cypher'})-[i:IN]->(g:TagGroup),
(t2:Tag {name:'neo4j'})-[:IN]->(g2:TagGroup)<-[y:TAGGED]-(x)
create (t2)-[:IN]->(g) 
create unique (g)<-[:TAGGED]-(x)
with g2 as g2 
match (g2)<-[r]->() delete g2,r

My main issues is that it only combines two nodes, and doesn't feel very efficient (although I have no alternatives to compare it with). Ideally I'd be able to combine an arbitrary set of (Tag)s by name.

Any ideas if this can be done with Cypher, and if so, how?

You can use labels instead of creating separate tag groups.

eg. if tag neo4j and cypher come under tag group say XYZ then

MERGE (a:Tag {name: "neo4j"})-[:TAGGED]->(x)
MERGE (b:Tag {name: "cypher"})-[:TAGGED]->(x)
set a :XYZ , b :XYZ

So next time you want tags of a particular group TAGGED to a particular post x

MATCH (a:Tag:XYZ)-[:TAGGED]->(x) return a.name

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM