Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.
10-27-2022 03:09 AM
It's me again! I'm onto my (hopefully) final question. I have a full text query (see below) that returns the data you can see in the attachment. Basically, n1 and n2, where, in each row, either n1 or n2 will contain the :Person I want to return.
I have been trying, in vain, apoc do/case and various other approaches.
So Basically, I just want to return a one dimensional list of p:Person, where p is taken from whichever of n1 or n2 is a :Person node.
I hope that's clear
Solved! Go to Solution.
10-27-2022 09:47 AM
Try this to see if it works. It doesn't require re-searching for the Person and Gig nodes. You can collect the nodes in the return statement if you want a collection, as you had in your last solution.
CALL db.index.fulltext.queryNodes("FT_Search", "state~", {limit: 100}) YIELD node, score
OPTIONAL MATCH (profileMatchedPerson:Person)-[:PROFILE]-(node:Profile)
WITH CASE node
WHEN node:Profile THEN profileMatchedPerson
ELSE node
END as result
RETURN DISTINCT result
10-27-2022 04:18 AM
What is your intent with each optional match? For the first, are you trying to find the person associated with each node returned from the full text search? What about the second match? How is it related to the full search results?
10-27-2022 04:51 AM
Please see attached screenshot. The full picture is
- I have a full text index on 5 fields across 3 nodes.
- I perform a text search and it returns the nodes that match (inset table in screenshot)
- The returned nodes could be a :Gig, :Person or :Profile
- If it is a :Profile node then I need to match it with it's owner :Person
- I want to be left with a list of :Person and :Gig nodes which I pass on the the next stage. This should be a one-dimensional list, so no cartesian products so it can be passed to the next stage.
I am more than happy if you tell me I am going about this in the wrong way, but this is my current approach.
It would be easy to solve if I broke it down into 2 completely separate queries where I first run the query I showed in my original question, processed this in code and then passed the results to a second query, but I would think there has to be a better way.
To answer your question about the second optional match is supposed to ensure that it only return :Person nodes and not :Profile nodes.
Thanks for your help and hope this is somehow clear enough
10-27-2022 05:40 AM
One other approach I did consider was to create a new :Search node linked to the :Person node that contains anything I might want to search on and just used that. This would simplify the index and the retrieval but it would require duplication and would involve a bit more complexity when saving fields that require the :Search node to be updated.
10-27-2022 09:19 AM
I got what I wanted in the end. I have no idea if this is the best or even a good way, but it works for all cases I tested.
10-27-2022 09:47 AM
Try this to see if it works. It doesn't require re-searching for the Person and Gig nodes. You can collect the nodes in the return statement if you want a collection, as you had in your last solution.
CALL db.index.fulltext.queryNodes("FT_Search", "state~", {limit: 100}) YIELD node, score
OPTIONAL MATCH (profileMatchedPerson:Person)-[:PROFILE]-(node:Profile)
WITH CASE node
WHEN node:Profile THEN profileMatchedPerson
ELSE node
END as result
RETURN DISTINCT result
10-28-2022 04:46 AM
The example you provided above didn't quite work. The ELSE condition was always triggered. I modified to the following to test it and it always returned 4
CALL db.index.fulltext.queryNodes("FT_Search", "state~", {limit: 100}) YIELD node
WITH node
OPTIONAL MATCH (profileMatchedPerson:Person)-[:PROFILE]-(node:Profile)
WITH CASE node
WHEN node:Profile THEN 1
WHEN node:Person THEN 2
WHEN node:Gig THEN 3
ELSE 4
END as result
RETURN DISTINCT result
I did use the CASE approach, however, and this works ...
CALL db.index.fulltext.queryNodes("FT_Search", "state~", {limit: 100}) YIELD node
OPTIONAL MATCH (profileMatchedPerson:Person)-[:PROFILE]-(node:Profile)
WITH node, profileMatchedPerson, CASE WHEN 'Person' IN LABELS(node) THEN node END as person
WITH COLLECT(person) + COLLECT(profileMatchedPerson) as combined
UNWIND combined as unwound
RETURN DISTINCT unwound
It's not as elegant looking as yours and I don't think it does any researching. I have a feeling that the COLLECTS/UNWINDS could be done better.
10-27-2022 10:16 AM
You're right about the courses. I've been too impatient. But I am getting there and have finally understood the way COLLECT and UNWIND affects the data. Not even started on apoc yet, but I'm getting more confident.
Despite the frustrations, I absolutely love Neo4J and with community members like you chiming in, it's very satisfying.
Btw - have you tried Graphileon for building dashboards etc? It seems pretty nice although I haven't go into it yet. Is there anything similar for dashboards or simple form editing you'd recommend?
Freddy
10-27-2022 01:10 PM
I agree with you on neo4j. I am building an app around it now and find it so much easier than a sql database, and it ideally models my data.
I have not used that tool, but it looks cool. I will check it out. A took a few have promoted here is NeoDash.
All the sessions of the conference are now available online