Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to define double nested array in schema #423

Closed
takotuesday opened this issue Mar 8, 2018 · 19 comments
Closed

How to define double nested array in schema #423

takotuesday opened this issue Mar 8, 2018 · 19 comments

Comments

@takotuesday
Copy link

I am trying to do the following:

// Schema definitions
const typeDefs = `
type Chart {
  name: String
  series: [Series]
}

type Series {
  name: String!
  data: [[Int, Float]]
}
`

where Series.data is an array of data points. Each data point is an array of x,y coordinates. For this use case a point cannot be an object with x,y keys, it must be an array. This fails to build because GraphQL does not like the definition of data: [[Int, Float]]. I have scoured the internet, GitHub, and stackoverflow. What is the solution/workaround for this? Thanks

@IvanGoncharov
Copy link
Member

IvanGoncharov commented Mar 8, 2018

GraphQL doesn't support tuples, but you can write this:

type Chart {
  name: String
  series: [Series]
}

type Series {
  name: String!
  data: [DataPoint]
}

type DataPoint {
  x: Int
  y: Float
}

@takotuesday
Copy link
Author

@IvanGoncharov thank you for the prompt response. Unfortunately as I mentioned in my original post, For this use case a point cannot be an object with x,y keys, it must be an array. The charting framework I'm using on the front end requires tuples for large data sets. The only work around with your suggestion is to normalize the data on the front end, converting a point from an object to an array. This is not performant and slows down the page load. Are you aware of a custom scalar tuple type? It seems like my use case shouldn't be that rare.

@IvanGoncharov
Copy link
Member

IvanGoncharov commented Mar 9, 2018

For this use case a point cannot be an object with x,y keys, it must be an array

Missed that. Another less than ideal solutions is:

type Series {
  name: String!
  data: [[Float]]
}

Are you aware of a custom scalar tuple type? It seems like my use case shouldn't be that rare.

My opinion is that GraphQL is more about modeling data than to adapting data to particular library/framework. If you think that GraphQL must have tuple support you need to answer this questionary:
image

Here is Lee talk where he explains every question: https://www.youtube.com/watch?v=mePT9MNTM98&feature=youtu.be&t=20m32s

  1. Can we enable it without a change to GraphQL?
  2. If so how awkward is it?

Personally, I think there is nothing awkward about having:

type DataPoint {
  x: Int
  y: Float
}

If you think differently please open a separate issue about adding tuple support to GraphQL and include answers to above questions into the description.

@Atokulus
Copy link

Atokulus commented Apr 16, 2020

Hi there
I believe, in case of large numeric datasets, data reduction (think about cellular networks) and reduction of computational workload is a valid reason for tuple support and should be another goal of GraphQL. Let's face it:

  • There is a plurality of use cases in IoT and industry which require datasets of [(Int, Float)] (Timestamp and Value) to be sent to a client for data visualization. Yet the workers' handheld devices are characterised by low performance and poor connection.
  • Data Analytics is an important domain in research and at larger companies (such as Facebook) and might benefit from better performance.

I am therefore "in favor of change"

Best regards

Markus Wegmann
Technokrat LLC

@mike-marcacci
Copy link
Contributor

mike-marcacci commented Apr 16, 2020

GraphQL doesn't specify the format of data over the wire; it only happens to most often be used with JSON because of its ease and relative efficiency when combined with gzip. If payload size is especially important to your use-case, it's probably more productive to explore changes to serialization than to the query language itself. For example, it's totally possible to compile a query into a highly-optimized serialization format that can omit structural data because it's known ahead of time.

Alternatively (and more simply), if you have no need for GraphQL's ability to request partial data or provide field arguments, your value is already effectively a scalar. If you'd like to define an ultra-concise format for something like IoT measurements or analytics, it's trivial to create a custom scalar for these values in GraphQL.

@klebba
Copy link

klebba commented Apr 22, 2020

Surprising limitation

@dlamon1
Copy link

dlamon1 commented Nov 24, 2020

The thumb ups in this thread are aggressive.

@doylemark
Copy link

Why is this closed?

@r0kk3rz
Copy link

r0kk3rz commented Jun 30, 2021

A +1 for including tuples is for incorporating the GeoJSON IETF standard as a type where the Geometry part is specified in float arrays [[float, float], ... ]

Instead of having to convert the nested arrays to objects, and then convert them back into arrays to maintain compatibility with the standard

Full example:

{
       "type": "Feature",
       "geometry": {
           "type": "Polygon",
           "coordinates": [
               [
                   [100.0, 0.0],
                   [101.0, 0.0],
                   [101.0, 1.0],
                   [100.0, 1.0],
                   [100.0, 0.0]
               ]
           ]
}

@thespacedeck
Copy link

+1 for adding support for GeoJSON

@benjie
Copy link
Member

benjie commented Jul 8, 2021

For GeoJSON I'm not sure how useful partial selection is, would it make more sense to use a custom scalar for GeoJSON so that each entry is its own atomic element? We could put up a shared specification at https://www.graphql-scalars.com/

@michaelstaib
Copy link
Member

michaelstaib commented Jul 8, 2021

We did solve this for HotChocolate with a custom scalar. The main issue at the moment is that there is no spec for such scalars and I am sure all of the GeoJson scalars have some quirks :).

@benjie a shared spec would be great to get tooling support on this.

@mahanfakhimi

This comment was marked as spam.

@mahanfakhimi

This comment was marked as spam.

@amaster507
Copy link

I work with HL7 v2.x messages, and storing them is difficult in any parsed way. The normal for most everything is store the entire message. I have not found any good way to store parsed HL7 messages besides multi-dimensional arrays. (I'm not a fan of JSON/XML strings/columns)

I support the idea of multi-dimensional array support in GraphQL spec.

By the way, This is not already supported as was hinted by @IvanGoncharov:

...Another less than ideal solutions is:

type Series {
  name: String!
  data: [[Float]]
}

If this was supported, then a tuple workaround would be a multi-dimensional array support of a Union of two types. (Cannot Union Scalars though AFAIK)

@benjie
Copy link
Member

benjie commented Oct 26, 2022

For clarity, data: [[Float]] is supported by GraphQL.

@fredcarle
Copy link

For clarity, data: [[Float]] is supported by GraphQL.

Does this imply that data: [[[Float]]] or more deeply nested variants are also supported?

@benjie
Copy link
Member

benjie commented Mar 13, 2024

Yes. There is no limit to the number of wrapping lists (and associated non-nulls) that you do in GraphQL, however you should be aware the GraphQL.js (and by extension GraphiQL) will by default only introspect 9 levels of wrappers so the deepest type to use for good compatibility would be: [[[[Int!]!]!]!]!

https://github.com/graphql/graphql-js/blob/9c90a23dd430ba7b9db3d566b084e9f66aded346/src/utilities/getIntrospectionQuery.ts#L131-L170

@benjie
Copy link
Member

benjie commented Mar 13, 2024

(Or, if you really wanted ridiculous depth: [[[[[[[[[Int]]]]]]]]].)

I've not seen any strong us cases past two levels of arrays, and even those do not seem particularly strong and generally better using either "named tuples" (i.e. objects with the tuple entries as named keys as described by Ivan above) or having an object inside the list which then contains the next list, allowing for additional properties to be added at each layer (and for you to stop selecting data).

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

No branches or pull requests