简体   繁体   中英

Search keywords in neo4j database by cypher query

在此处输入图片说明 I'm working on a website and implementing search filter functionality.I am fetching search result from data base which is neo4j. I'm facing an problem in applying filters.The problem is when add for search let say Bangalore I get 10 result then I add another keyword let developer I get the result from the whole database but what i want it should be come from only previous selected result or Keyword that is Bangalore

My query is:

        $data = array (
           "query" => "MATCH (x :Job)-[r :POSTED_JOB]-(m) where ( x.city IN {data1} or x.categories or x.sectors IN {data4} or x.role IN {data5} or x.requirement IN {data6} 
            or x.title IN {data7} or x.description IN {data8})
            RETURN m.companyName,x.city",
       "params" => array(
                "data1" => $city,
                "data4" => $sector,
                "data5" => $skills,
                "data6" => $search,
                "data7" => $search,
                "data8" => $search

) );

How can I write this query to refine the result.

Your query is full of OR s which means that a Job will match when any of the (that array contains two data5 properties). If you want to match all of the provided criteria then swap the OR s for AND s. Depending on the data you are providing you may need to be careful of NULL values and empty lists.

EDIT - example code

This is the small section of your query that I think probably matches the fields you are talking about.

WHERE x.city IN {data1} OR x.role IN {data5}

It says match me any Node (x) WHERE x is in Bangalore OR WHERE x is for a developer role. If you want your query to match only records which are both in Bangalore and for a Developer then that section of query should be:

WHERE x.city IN {data1} AND x.role IN {data5}

x.categories seems a little stranded too (you're not querying anything but its existence).

EDIT - Post Chat

The requirement is to perform successive queries where each query acts as a filter on the previous result. All fields are re-matched with each call. To achieve this you need to have an external node identifier that you can use to chain queries and then pass the set of identifiers into each successive query. A reduced example in Cypher:

Initial Query:

MATCH (j:Job)<-[:POSTED_JOB]-(m)
WHERE j.title=~{searchString} OR j.description=~{searchString}
RETURN j.jobId, j.title, j.description, j.city, m.companyName

Subsequent Queries:

MATCH (j:Job)<-[:POSTED_JOB]-(m)
WHERE j.jobId IN {collectionOfJobIds}
AND (j.title=~{searchString} OR j.description=~{searchString})
RETURN j.jobId, j.title, j.description, j.city, m.companyName

EDIT - Because it is bugging me

You might want to rematch your data on each query, so you can employ a filter:

MATCH (j:Job)<-[:POSTED_JOB]-(m)
WHERE j.title=~({searchStrings}[0]) OR j.description=~({searchStrings}[0])
WITH m, COLLECT(j) as jobs
WITH m, FILTER (j IN jobs WHERE j.title=~({searchStrings}[1]) OR j.description=~({searchStrings}[1]) as filteredJobs
RETURN m, jobs

This requires passing in the searchStrings as an array, and you can add as many WITHs as you like (just remember to increment your array index). It is important to realise that with all of these queries, if you have very many Jobs, they are going to be slow as you are begin by matching all the Jobs in your system. If you can put some restriction on the initial Match your life will be better!

ASIDE: Your model is not really a graph though where you would possibly model City, Sector, Skills, etc as Nodes rather than properties.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM