Skip to content

Instantly share code, notes, and snippets.

@tekiegirl
Forked from peterneubauer/fuzzy_match.adoc
Last active December 29, 2015 06:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tekiegirl/7631782 to your computer and use it in GitHub Desktop.
Save tekiegirl/7631782 to your computer and use it in GitHub Desktop.

Ranked rule-based subgraph matching

In order to rank possible matches by relevence I wish to return a score, with different matches addingg a different value to the score, and a list of the items that matched (a list of strings). More matches the higher the rank should be.

Setup of known data

CREATE (p1:Person{first_name:'Jacqui',last_name:'Miller'})-[:HAS_ADDRESS]->(a1:Address{line1:'22 High Street',city:'London',postcode:'W2'})
CREATE (p2:Person{first_name:'Jacqui',last_name:'Smith'})-[:HAS_ADDRESS]->(a2:Address{line1:'Union square',city:'London',postcode:'SW1'})

Find a person by partly matching properties

In this example, find the persons that best match:

  • have a mandatory first name Jacqui

  • have a last name if Smith

  • live on a street name with square in it

MATCH (p:Person)
//first name match
WHERE p.first_name='Jacqui'
WITH p, 1 as score, ["first_name"] as matched_rules
//last_name match
WITH p,
  CASE WHEN p.last_name='Smith'
  THEN score+1
  ELSE score
  END as score,
  CASE WHEN p.last_name='Smith'
  THEN matched_rules+["last_name"]
  ELSE matched_rules
  END as matched_rules
//address_match
MATCH p-[:HAS_ADDRESS]->(a:Address)
WITH p,
  CASE WHEN a.line1=~'.*square.*'
  THEN score+0.5
  ELSE score
  END as score,
  CASE WHEN a.line1=~'.*square.*'
  THEN matched_rules+["address_line1"]
  ELSE matched_rules
  END as matched_rules
RETURN p, score, matched_rules
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment