Skip to content
This repository was archived by the owner on Sep 3, 2021. It is now read-only.

Wrong generated query when using interfaces #548

Open
nardo7 opened this issue Nov 27, 2020 · 4 comments
Open

Wrong generated query when using interfaces #548

nardo7 opened this issue Nov 27, 2020 · 4 comments

Comments

@nardo7
Copy link

nardo7 commented Nov 27, 2020

Bug

Hi guys, I want to report what I think it's a bug which is not letting us go forward with our graphql API using your framework.

Our project uses the same version as in the starter project: neo4j-graphql-js 2.17.0

I'm experiencing some troubles with your framework, receiving wrong data in some queries which were working well until I started to use interfaces. After watching the generated cypher queries I figured out that the interface label is generated as variable name instead of generating the variable name of the type which implements the interface.

I tried to reproduce the problem with the grandstack starter project.

Schema

interface Entity {
  name: String!
  descriptions:[DescriptionRel]
}

type Description {
  DescriptionID:ID! 
  description:String
  created_at:Date
  entity: DescriptionRel
}

type DescriptionRel @relation(name: "DESCRIPTION") {
  lang:String
  from: Entity
  to: Description
}


type Business implements Entity {
  businessId: ID!
  address: String
  name: String!
  descriptions:[DescriptionRel]
  city: String
  state: String
  location: Point
  avgStars: Float
    @cypher(
      statement: "MATCH (this)<-[:REVIEWS]-(r:Review) RETURN coalesce(avg(r.stars),0.0)"
    )
  reviews: [Review] @relation(name: "REVIEWS", direction: "IN")
  categories: [Category] @relation(name: "IN_CATEGORY", direction: "OUT")
}

type User {
  userId: ID!
  name: String
  reviews: [Review] @relation(name: "WROTE", direction: "OUT")
  avgStars: Float
    @cypher(
      statement: "MATCH (this)-[:WROTE]->(r:Review) RETURN toFloat(avg(r.stars))"
    )
  numReviews: Int
    @cypher(statement: "MATCH (this)-[:WROTE]->(r:Review) RETURN COUNT(r)")
  recommendations(first: Int = 3): [Business]
    @cypher(
      statement: "MATCH (this)-[:WROTE]->(r:Review)-[:REVIEWS]->(:Business)<-[:REVIEWS]-(:Review)<-[:WROTE]-(:User)-[:WROTE]->(:Review)-[:REVIEWS]->(rec:Business) WHERE NOT EXISTS( (this)-[:WROTE]->(:Review)-[:REVIEWS]->(rec) ) WITH rec, COUNT(*) AS num ORDER BY num DESC LIMIT $first RETURN rec"
    )
}



type Review {
  reviewId: ID!
  stars: Float
  text: String
  date: Date
  business: Business @relation(name: "REVIEWS", direction: "OUT")
  user: User @relation(name: "WROTE", direction: "IN")
}

type Category {
  name: ID!
  businesses: [Business] @relation(name: "IN_CATEGORY", direction: "IN")
}

type RatingCount {
  stars: Float!
  count: Int!
}

type Mutation {
  mergeBusinessCategory(categories: [String!]!, businessId: ID!): Business
    @cypher(
      statement: "MATCH (b:Business {businessId: $businessId}) UNWIND $categories AS cat MERGE (c:Category {name: cat}) MERGE (b)-[:IN_CATEGORY]->(c) RETURN b"
    )
}

type Query {
  userCount: Int! @cypher(statement: "MATCH (u:User) RETURN COUNT(u)")
  ratingsCount: [RatingCount]
    @cypher(
      statement: "MATCH (r:Review) WITH r.stars AS stars, COUNT(*) AS count ORDER BY stars RETURN {stars: stars, count: count}"
    )
}

Graphql Query

After creating this dumm elements

mutation create{
  CreateBusiness(businessId:999999,name:"test"){
    businessId
    name
  }
  CreateDescription(DescriptionID:1,description:"hello world"){
    DescriptionID
    description
  }
  AddDescriptionEntity(from:{name:"test"},to:{DescriptionID:1},data:{lang:"en"}){
    from{
      name
    }
    to{
      DescriptionID
      DescriptionID
    }
    lang
  }
}

This is the query I need to work

query bussiness{
  Business(businessId:999999){
    businessId
    descriptions(filter:{
      OR:[{lang:"de"},
      {Description:{description_not:""}}
      ]
      }){
      lang
      Description{
        description
      }
    }
  }
}

The generated Query

MATCH (`business`:`Business` {businessId:$businessId}) RETURN `business` 
{ .businessId ,

descriptions: [(`business`)-[`business_descriptions_relation`:`DESCRIPTION`]->(:`Description`) WHERE 
(ANY(_OR IN $1_filter.OR WHERE 
(_OR.lang IS NULL OR `business_descriptions_relation`.lang = _OR.lang) AND 
(_OR.Description IS NULL OR ALL(`description` IN 
**[(`entity`)-[`entity_filter_description`]->(`_description`:Description) | `_description`]** WHERE 
(_OR.Description.description_not IS NULL OR NOT `description`.description =  _OR.Description.description_not))))) | 
business_descriptions_relation { 
    .lang ,Description: head([(:`Entity`)-[`business_descriptions_relation`]->(`business_descriptions_Description`:`Description`) | 
    business_descriptions_Description { .DescriptionID , .description }]) }] } AS `business`

I think the part [(`entity`)-[`entity_filter_description`]->(`_description`:Description) | `_description`] is wrong, because:

  1. It retrieves every node from the database which has a connection with every Description
  2. In my real case, I have thousands of nodes which fill this part of the query query, therefore this query doesn't returns what I want
  3. In the part of the query (`entity`) should be generated (`business`) instead.

I tested it myself replacing the entity for the real label and it worked as I expected.

What can I do? Am I missing something here?

Thank for your work and for your help

@gabriellovric
Copy link

Hey I experienced similar problems and wrote a fix for this in #527.

I would be happy to hear if this works for you too.

@nardo7 nardo7 closed this as completed Dec 10, 2020
@nardo7 nardo7 reopened this Dec 10, 2020
@nardo7
Copy link
Author

nardo7 commented Dec 10, 2020

Hi @gabriellovric
Thanks for your help. I’ll look at it for sure! I’ll let you know

@nardo7
Copy link
Author

nardo7 commented Dec 14, 2020

Hi @gabriellovric
It doesn't resolve my issue. I think your fix isn't related with this, since the function you modified isn't called at all when I run the query example.
Thanks for your help

@michaeldgraham
Copy link
Collaborator

#608

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants