Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.
06-23-2020 04:55 AM
I want to search nodes that only have a specific relationship efficiently.
Example
CREATE (a:Asset {asset_name:'John', asset_id:'001'})
CREATE (as:Asset {asset_name:'John', asset_id:'002'})
CREATE (g:Group {group_name:'local_employee'})
MERGE (g)-[:GROUP]-(as)
call db.index.fulltext.createNodeIndex('search', ['Asset'], ['asset_name'], {analyzer:'standard-no-stop-words'})
call db.index.fulltext.queryNodes('search', 'john')
However this will return both nodes. I just want to return the one asset node that has the relationship.
I understand that you can just add a match statement at the bottom and then return the results. However this method is inefficient when the nodes I have to search through are in the tens of thousands.
Basically I require a more efficient method.
Solved! Go to Solution.
06-25-2020 01:43 AM
CALL db.index.fulltext.queryNodes('livesearch', '*a*')
YIELD node
WHERE EXISTS ((:Group)-[:GROUPS]->(node)<-[:ON]-(:Deploy)<-[:SCHEDULED]-(:Device))
OR EXISTS ((node)-[:GROUPS]->(:Asset)<-[:ON]-(:Deploy)<-[:SCHEDULED]-(:Device))
OR EXISTS ((:Group)-[:GROUPS]->(:Asset)<-[:ON]-(:Deploy)<-[:SCHEDULED]-(node))
RETURN node
06-23-2020 08:45 AM
06-23-2020 06:51 PM
Hello @Cobra . Sorry should have provided it.
WITH ("*" +$usersearchtext+ "*") as txt
WITH split(txt,' ') as stxt
WITH apoc.text.join(stxt, '* AND *') as jtxt
CALL db.index.fulltext.queryNodes('livesearch', jtxt)
YIELD node
MATCH (g:Group)-[:GROUP]->(a:Asset)-[:OWNS]->(d:Device)
WHERE a.asset_name = node.asset_name
RETURN (a)
06-24-2020 02:26 AM
First, I think you can remove all the WITH
clauses and build your string directly in the CALL
Moreover you can do this:
CALL db.index.fulltext.queryNodes('search', 'john')
YIELD node WHERE exists((node)<-[:GROUP]-(:Group))
RETURN node
Regards,
Cobra
06-24-2020 10:41 PM
I tried doing what you said however it didnt work. It still returned all without filtering. Only if I put the match then it will filter.
06-25-2020 12:45 AM
Hello @tarendran.vivekanand
The cypher request I showed you works on my database
Which version of Neo4j are you using?
Regards,
Cobra
06-25-2020 01:06 AM
Hello @Cobra 🙂
Im using the latest one Neo4j 4.0
When I use the match on the outside
CALL db.index.fulltext.queryNodes('livesearch', '*a*')
YIELD node
OPTIONAL MATCH (g:Group)-[:GROUPS]->(a:Asset)<-[:ON]-(:Deploy)<-[:SCHEDULED]-(d:Device)
WHERE a.asset_id = node.asset_id
WITH DISTINCT collect(d{.sigfox_id,a}) as assetdata
When I use yours
CALL db.index.fulltext.queryNodes('livesearch', '*a*')
YIELD node WHERE EXISTS ((:Group)-[:GROUPS]->(:Asset)<-[:ON]-(:Deploy)<-[:SCHEDULED]-(:Device))
return node
06-25-2020 01:10 AM
I'm using the version 4.0.4 of Neo4j, otherwise I don't know why it works on my database and not on yours
The WHERE
clause checks if there is a relationship linked to the node or not.
06-25-2020 01:13 AM
I just edited my comment with my query and results
06-25-2020 01:16 AM
@tarendran.vivekanand can you try to return only the node id on my cypher request ?
06-25-2020 01:19 AM
Can you give me all the queries to build the same database as yours?
06-25-2020 01:31 AM
06-25-2020 01:34 AM
You must use the node
return by the db.index.fulltext.queryNodes
in the WHERE
clause
CALL db.index.fulltext.queryNodes('livesearch', '*a*')
YIELD node WHERE EXISTS ((:Group)-[:GROUPS]->(node)<-[:ON]-(:Deploy)<-[:SCHEDULED]-(:Device))
return node
06-25-2020 01:40 AM
Then what if I want to return all so the asset,group and device?
06-25-2020 01:43 AM
CALL db.index.fulltext.queryNodes('livesearch', '*a*')
YIELD node
WHERE EXISTS ((:Group)-[:GROUPS]->(node)<-[:ON]-(:Deploy)<-[:SCHEDULED]-(:Device))
OR EXISTS ((node)-[:GROUPS]->(:Asset)<-[:ON]-(:Deploy)<-[:SCHEDULED]-(:Device))
OR EXISTS ((:Group)-[:GROUPS]->(:Asset)<-[:ON]-(:Deploy)<-[:SCHEDULED]-(node))
RETURN node
06-25-2020 01:45 AM
All the sessions of the conference are now available online