Roman March
Roman March

Reputation: 73

How to implement faceted search with cypher?

I have a kinda faceted search task to my domain model.

I have a graph that consists of two parts:

  1. (:TAG)'s hierarhical tree with -[:IS_A]-> relations between parent tags and it's child(s). Note, that each banch of the tree has different levels of depth. Every (:TAG) node has unique "name" (String) propery
  2. Individual (:IMG) nodes, that have unique "name" (String) and "href" (String) properties.
  3. Every (:IMG) is connected to at least one (:TAG) with the relation (:TAG)-[:DESCRIBES]->(:IMG), but there could be (:TAG) nodes that don'c connect with any of (:IMG) nodes. enter image description here

I need to be able to tell any amount of tag's "names" and to be responsing all intersecting images nodes, but with following logic: If every two (:TAG) nodes has similar parent (:TAG) node, so I need to response images conencted to both of them, else (if they have different parent (:TAG) node), so I need to response only images that connect to both of them at the same time.

--

What I already know:

  1. If I want to get images that are conencted to only intersecting tags (tag1 or tag2 or tag3), so I need the following query:
MATCH
(img:IMG)<-[*]-(:TAG {name:'Tag Name A'}),
(img:IMG)<-[*]-(:TAG {name:'Tag Name B'}),
(img:IMG)<-[*]-(:TAG {name:'Tag Name C'})
RETURN img
  1. If I want to get images that are connected to every tag (tag1 and tag2 and tag3), so I need the following query:
MATCH (img:TEST_01_Img)
WHERE
(img)<-[*]-(:TAG {name:'Tag Name A'})
OR
(img)<-[*]-(:TAG {name:'Tag Name B'})
OR
(img)<-[*]-(:TAG {name:'Tag Name C'})
RETURN img

And I think have to somehow combine these two methods with (if...else) logic of combining results if images have same tag's parent and intersecting them if they have different tag's parents.

Maybe I need to use Conditional Cypher Execution, but I have no idea how, cuz I'm very new to this.

Thank you very much for your help in advance!

Upvotes: 0

Views: 327

Answers (1)

Yes you can combine match [pattern] with where [pattern]. Example:

// Tagged A and B
MATCH (img)<-[*]-(:TAG {name:'Tag Name A'})
WHERE (img)<-[*]-(:TAG {name:'Tag Name B'})

// Tagged A but not B
MATCH (img)<-[*]-(:TAG {name:'Tag Name A'})
WHERE NOT (img)<-[*]-(:TAG {name:'Tag Name B'})

See Using Patterns in Where (https://neo4j.com/docs/cypher-manual/current/clauses/where/#query-where-patterns)

Upvotes: 1

Related Questions