Neo4j-grapql-js custom cypher query

I'm attempting to create a custom cypher query through the neo4j-graphql-js driver. I've found the documentation pretty useful but for some reason I'm getting stuck. I've created this query in my schema:

type Query {
  mineralTotal(name: String): Float 
  @cypher (
    statement: "MATCH (:Tract)<-[r:MINERAL_OWNERSHIP]-(:Owner {name: $name}) return sum(r.net_mineral_acres)"
    )
}

When I attempt to run this in the GraphiQL playground like this:

query{
  mineralTotal(name: "mpi")
}

The error message I get back is: "Cannot read property 'selections' of undefined". I'm sure it's because I'm not specifying a return but I don't know what to ask for back? Any suggestions?

try

" ... return sum(r.net_mineral_acres) as sum_net_mineral_acres"

Thanks for the suggestion. I went ahead and did something different. I placed it on the owner type by itself as:

totalSurface: Float 
  @cypher (
    statement: "MATCH (:Tract)<-[r:SURFACE_OWNERSHIP]-(this) return sum(r.net_surface_acres)"
  )
  totalMinerals: Float 
  @cypher (
    statement: "MATCH (:Tract)<-[r:MINERAL_OWNERSHIP]-(this) return sum(r.net_mineral_acres)"
  )

and now when I query Owners I can just ask for totalSurface or totalMinerals

I went ahead and tried this to see if it would work and it did not. I think that it has to return a type to be a valid query.

Sorry I am not familar with neo4j-grapql-js, just generally a cypher query requires any aggreation to be given an as name.

No worries. Thank you for your suggestion.

Hey @MuddyBootsCode I remember running across this before - it seems we hadn't considered the case where a custom Query field would return a scalar and not an object.

As a workaround you could try adding mineralTotal as a field on the Owner type, instead of on the root query:

type Owner {
  name: ID!
  mineralTotal: Float @cypher(statement:"MATCH (:Tract)<-[r:MINERAL_OWNERSHIP]-(this) RETURN sum(r.net_mineral_acres")
}

Then your GraphQL query would be:

{
  Owner(name: "mpi") {
      name
      mineralTotal
  }
}

@lyonwj Thanks for that. I ended up doing something similar and got a lot of queries made.

Cool! Glad you got it working.

BTW - you can use the auto-generated ordering field orderBy with these custom computed fields as well, just be aware that if your graph is large enough you might see some performance impacts as those sub-queries will be run over every Owner node to be able to sort.

2 Likes

@lyonwj

I have no idea what happened but literally overnight the code that was working to create these queries broke. Now when I try to run any of the queries that were working before like:

query{
  Owner{
    name
    totalSurface
    totalMinerals
  }
}

I get errors,

"message": "Invalid input '}': expected whitespace, comment or a property key name (line 1, column 185 (offset: 184))\r\n\"MATCH (`owner`:`Owner` ) RETURN `owner` { .name ,totalSurface: apoc.cypher.runFirstColumn(\"MATCH (:Tract)<-[r:SURFACE_OWNERSHIP]-(this) return sum(r.net_surface_acres)\", {this: owner, }, false),totalMinerals: apoc.cypher.runFirstColumn(\"MATCH (:Tract)<-[r:MINERAL_OWNERSHIP]-(this) return sum(r.net_mineral_acres)\", {this: owner, }, false)} AS `owner` SKIP $offset\"\r\n                                                                                                                                                                                         ^"

I've done nothing. No updates, no changes to the code. But this was all working when I did the queries from the previous posts and now. Nothing. Any ideas?

Queries

totalSurface: Float 
  @cypher (
    statement: "MATCH (:Tract)<-[r:SURFACE_OWNERSHIP]-(this) return sum(r.net_surface_acres)"
  )
  totalMinerals: Float 
  @cypher (
    statement: "MATCH (:Tract)<-[r:MINERAL_OWNERSHIP]-(this) return sum(r.net_mineral_acres)"
  )

Error Stack Trace

"    at captureStacktrace (/Users/mbp/WebstormProjects/landmachine_api/node_modules/neo4j-driver/lib/v1/result.js:200:15)",
            "    at new Result (/Users/mbp/WebstormProjects/landmachine_api/node_modules/neo4j-driver/lib/v1/result.js:73:19)",
            "    at _newRunResult (/Users/mbp/WebstormProjects/landmachine_api/node_modules/neo4j-driver/lib/v1/transaction.js:342:10)",
            "    at Object.run (/Users/mbp/WebstormProjects/landmachine_api/node_modules/neo4j-driver/lib/v1/transaction.js:251:14)",
            "    at Transaction.run (/Users/mbp/WebstormProjects/landmachine_api/node_modules/neo4j-driver/lib/v1/transaction.js:120:26)",
            "    at /Users/mbp/WebstormProjects/landmachine_api/node_modules/neo4j-graphql-js/dist/index.js:78:25",
            "    at TransactionExecutor._safeExecuteTransactionWork (/Users/mbp/WebstormProjects/landmachine_api/node_modules/neo4j-driver/lib/v1/internal/transaction-executor.js:136:22)",
            "    at TransactionExecutor._executeTransactionInsidePromise (/Users/mbp/WebstormProjects/landmachine_api/node_modules/neo4j-driver/lib/v1/internal/transaction-executor.js:124:32)",
            "    at /Users/mbp/WebstormProjects/landmachine_api/node_modules/neo4j-driver/lib/v1/internal/transaction-executor.js:67:15",
            "    at new Promise (<anonymous>)"

So the issue looks to be the generated Cypher query includes a trailing , in the parameters object passed to apoc.cypher.runFirstColumn:

{this: owner, } instead of {this: owner}

which causes the Cypher syntax error. Which version of neo4j-graphql-js are you using? You can run

npm ls neo4j-graphql-js

to list the installed version.


My current package.json

Could you try pinning to version 2.3.1? We updated some of the handling for scalar Cypher directive fields in 2.4.0 and I wonder if maybe we broke something there.

I’ll give it a shot here shortly.

That did the trick. I think you've found your culprit.

Glad that fixed it and sorry for introducing the error. I've created an issue here to track the fix. Thanks for reporting!

I'm trying to let the client demo the app this weekend. I saw my life crumbling before my eyes :stuck_out_tongue:

I should add that this occurred with every cypher query in the schema. Not just those two.