I'd like to order returned data by relevance in Neo4j.
For my purpose, relevance can be simplified to "Index of the word I'm searching for", where the lower index the higher relevance.
Example
I have these three nodes:
node : {
Label: PROD
properties : {
name: "Bearing replacement Skateboard"
}
}
node : {
Label: PROD
properties : {
name: "Skateboard"
}
}
node : {
Label: PROD
properties : {
name: "L7 Skateboard"
}
}
I want them to be returned with this order:
node : {
Label: PROD
properties : {
name: "Skateboard" // name.indexOf("Skateboard") = 0
}
}
node : {
Label: PROD
properties : {
name: "L7 Skateboard" // name.indexOf("Skateboard") = 3
}
}
node : {
Label: PROD
properties : {
name: "Bearing replacement Skateboard" // name.indexOf("Skateboard") = 19
}
}
What I have so far:
String query = "MATCH (n:PROD) where LOWER(n.name) CONTAINS LOWER({textToSearch}) RETURN n ORDER BY LOWER(n.name) ASC LIMIT 15";
String textToSearch = "Skateboard";
Map<String, Object> queryParams = new HashMap<>();
queryParams.put("textToSearch", textToSearch);
try (
Transaction ignored = database.beginTx();
Result resultSet = database.execute(query, queryParams)
) {
Iterator<Node> results = resultSet.columnAs("n");
while (results.hasNext()) {
Node node = results.next();
/* data processing here */
}
}
This just orders results by name ascendant. Is there a way to tell neo4j to sort based on n.name.indexOf({textToFind})
?
How about doing something like this in Cypher
MATCH (n:PROD)
WHERE n.name_lc CONTAINS toLower({textToSearch})
WITH n, SPLIT(n.name_lc, toLower({textToSearch})) as parts
RETURN n.name, SIZE(parts[0]) AS leading
ORDER BY leading
To make effective use of the above...
Create an index on a lowercase version of the property
CREATE INDEX ON :PROD(name_lc)
Copy the regular name to a lowercase version
MATCH (n:PPOD)
SET n.name_lc = toLower(n.name)