neo4j-graphql / neo4j-graphql-js

NOTE: This project is no longer actively maintained. Please consider using the official Neo4j GraphQL Library (linked in README).
Other
608 stars 148 forks source link

Nested fields for Cypher queries #284

Open mneedham opened 5 years ago

mneedham commented 5 years ago

Given this schema:

type Club {
   _id: Long!
   id: String!
   image: String
   name: String!
   in_league: League @relation(name: "IN_LEAGUE", direction: "OUT")
   transfers_from_club: [Transfer] @relation(name: "FROM_CLUB", direction: "IN")
   transfers_to_club: [Transfer] @relation(name: "TO_CLUB", direction: "IN")
}

type Transfer {
   _id: Long!
   date: Date!
   id: String!
   value: Float!
   of_player: [Player] @relation(name: "OF_PLAYER", direction: "OUT")
   from_club: [Club] @relation(name: "FROM_CLUB", direction: "OUT")
   to_club: [Club] @relation(name: "TO_CLUB", direction: "OUT")
}

type League {
   _id: Long!
   href: String
   id: String!
   name: String!
   in_country: Country @relation(name: "IN_COUNTRY", direction: "OUT")
   clubs: [Club] @relation(name: "IN_LEAGUE", direction: "IN")
}

type Country {
   _id: Long!
   name: String!
   leagues: [League] @relation(name: "IN_COUNTRY", direction: "IN")
}

type Spending2 {
    club: Club
    country: Country
    moneySpent: Int
    moneyReceived: Int
    profit: Int
}

With this custom type using a Cypher query:

type Query {
    spendingByClub2(countrySubstring: String = ""): [Spending2]
    @cypher(
        statement: """MATCH (club:Club)-[*2]->(country:Country)
        WHERE country.name CONTAINS $countrySubstring
        WITH club, country,
        apoc.coll.sumLongs([(club)<-[:TO_CLUB]-(t) | t.value]) AS moneyOut,
        apoc.coll.sumLongs([(club)<-[:FROM_CLUB]-(t) | t.value]) AS moneyIn
        RETURN { club: club, country: country, moneySpent: moneyOut, moneyReceived: moneyIn, profit: moneyIn - moneyOut}"""
    )
}

If I then execute this GraphQL query:

query {
  spendingByClub2 {
    club {
      name
    }
    moneySpent
  }
}

I get the following exception:

"code": "INTERNAL_SERVER_ERROR",
        "exception": {
          "stacktrace": [
            "TypeError: Cannot read property '0' of undefined",
            "    at buildCypherSelection (/home/markhneedham/projects/football-transfers-app/api/node_modules/neo4j-graphql-js/dist/selections.js:321:20)",
            "    at customQuery (/home/markhneedham/projects/football-transfers-app/api/node_modules/neo4j-graphql-js/dist/translate.js:531:68)",
            "    at translateQuery (/home/markhneedham/projects/football-transfers-app/api/node_modules/neo4j-graphql-js/dist/translate.js:477:12)",
            "    at cypherQuery (/home/markhneedham/projects/football-transfers-app/api/node_modules/neo4j-graphql-js/dist/index.js:146:40)",
            "    at _callee$ (/home/markhneedham/projects/football-transfers-app/api/node_modules/neo4j-graphql-js/dist/index.js:49:31)",
            "    at tryCatch (/home/markhneedham/projects/football-transfers-app/api/node_modules/regenerator-runtime/runtime.js:62:40)",
            "    at Generator.invoke [as _invoke] (/home/markhneedham/projects/football-transfers-app/api/node_modules/regenerator-runtime/runtime.js:296:22)",
            "    at Generator.prototype.<computed> [as next] (/home/markhneedham/projects/football-transfers-app/api/node_modules/regenerator-runtime/runtime.js:114:21)",
            "    at step (/home/markhneedham/projects/football-transfers-app/api/node_modules/babel-runtime/helpers/asyncToGenerator.js:17:30)",
            "    at /home/markhneedham/projects/football-transfers-app/api/node_modules/babel-runtime/helpers/asyncToGenerator.js:35:14"
          ]
Joshfindit commented 5 years ago

Just for clarity: Are you able to run the Cypher query directly, say through Neo4j browser?

mmmoli commented 5 years ago

Assuming your answer to @Joshfindit is yes… welcome to #144.

Why 144? Follow the advice of @johnymontana by adding a @relation to your Spend2 type:

type Spending2 {
    club: Club @relation(name: "IS_CLUB", direction: "OUT")
    country: Country @relation(name: "IS_COUNTRY", direction: "OUT")
    moneySpent: Int
    moneyReceived: Int
    profit: Int
}

Unfortunately, this still doesn't do what you want it to because don't actually have IS_CLUB and IS_COUNTRY relationships in your DB. #smashesHeadAgainstWall

At least we can try to solve this project together now.

michaeldgraham commented 3 years ago

https://github.com/neo4j-graphql/neo4j-graphql-js/issues/608