Reputation: 33
I have a requirement where I want to add weights to the node labels and return the queried list based on these weights. Suppose a person node has two labels company and title and a search query matches both these fields, since the company label has more weight assigned, it should be returned on top of the list. I have created FULLTEXT index on node labels for search already.
Is it possible to do something like this with neo4j ?
Upvotes: 1
Views: 84
Reputation: 6514
Lucene query language also supports boosting the score of the results with the caret (^) operator. Suppose you add a string property called weight
to all your nodes.
Create a sample dataset:
CREATE (:Person {name:"Joan" , weight:"1"}),
(:Company {name:"Joan" , weight:"2"}),
(:Movie {name:"Joan" , weight:"3"})
Now create a full text index:
CREATE FULLTEXT INDEX example IF NOT EXISTS
FOR (n:Person|Company|Movie)
ON EACH [n.name, n.weight]
Finally, you can query the index and provide custom boosting options:
CALL db.index.fulltext.queryNodes("example", "name:Joan weight:1^1 weight:2^2 weight:3^3")
YIELD node, score
RETURN node.name, labels(node)[0] AS label, score
Results:
Table Text Code
╒═══════════╤═════════╤══════════════════╕
│"node.name"│"label" │"score" │
╞═══════════╪═════════╪══════════════════╡
│"Joan" │"Movie" │1.3981904983520508│
├───────────┼─────────┼──────────────────┤
│"Joan" │"Company"│0.9523590207099915│
├───────────┼─────────┼──────────────────┤
│"Joan" │"Person" │0.5065275430679321│
└───────────┴─────────┴──────────────────┘
You can see how movie comes up with the highest score as it has the largest weight. And yes, you probably need to include the weight for every node, I don't know how to do something generic on node label level, except if you customize the lucene index yourself. Learn more about that in: https://neo4j.com/docs/java-reference/current/extending-neo4j/full-text-analyzer-provider/
Upvotes: 0