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

Extend "StringOperators" with "OR" and RegEx #543

Closed
chladog opened this issue Nov 4, 2020 · 4 comments
Closed

Extend "StringOperators" with "OR" and RegEx #543

chladog opened this issue Nov 4, 2020 · 4 comments
Milestone

Comments

@chladog
Copy link
Contributor

chladog commented Nov 4, 2020

Is your feature request related to a problem? Please describe.
Currently only "eq" and "contains" filters that take single value are possible for strings. But sometimes we want to query for string OR string, or even write more complex check using RegEx.

Describe the solution you'd like

  • allow "eq" and "contains" operators to take || (OR) operator - should be possible to chain 1 and more strings. (e.g. I want to query all orders of state: "Shipped" OR "Delivered" OR "PartiallyDelivered")
    In practice the eq and contains could take in string | string[]. If an array is passed then it would do OR operations between array strings. E.g: { filter: state: { eq: ['Shipped', 'Delievered', 'PartiallyDelievered'] } }
  • add new "regex" operator that takes regular expression

The OR operation itself would be possible to do in RegEx itself, but extending current eq and contains shall be more straight-forward.

@michaelbromley michaelbromley added this to the v0.17.0 milestone Nov 4, 2020
@michaelbromley
Copy link
Member

michaelbromley commented Nov 6, 2020

One point to note is that in GraphQL we cannot have an input type like this:

input StringOperators {
    eq: String | [String!]
    contains: String | [String!]
}

This is because there is no support for union types in inputs: graphql/graphql-spec#488

Therefore there are 2 options:

  1. Change the type of eq to always be an array, and only pass a single value to get the same behaviour as currently.
  2. Add a new input field e.g. in: [String!] which is specifically for multiple values with boolean OR.

I prefer version 2 because it is more explicit (it may be confusing why you need to pass an array of 1 value to eq if you just want to do a simple match). Using in also matches how other APIs like SQL or MongoDB work, so will have some familiarity already.

Example:

query {
  orders(options: {
    filter: {
      state: {
        in: ["Shipped", "Delievered", "PartiallyDelievered"]
      }
    }
  }) {
    items {
      id
      # ...
    }
    totalItems
  }
}

@chladog
Copy link
Contributor Author

chladog commented Nov 6, 2020

I agree, in that case in: [String!] is perfect alternative. (y)

@chladog
Copy link
Contributor Author

chladog commented Nov 6, 2020

we can omit contains in multiple values as it's more advance use case that can be implemented by using RegEx.

@chladog
Copy link
Contributor Author

chladog commented Nov 23, 2020

Opening this topic again in pursuance of inverted string filters that would allow us to query for all values that are NOT:
eg:

  orders(options: {
    filter: {
      state: {
        **not**: ["AddingItems", "ArrangingPayment"]
      }
    }
  }

Ofc we can enlist all values we want, but having option to exclude values instaed would be handy and allows writing update-safe components (e.g. we add new "processing" order state and we might forget to include such state in "in" filter, where we aim to filter-out not placed orders.
(not perfect example as we can filter based on existence "orderPlacedAt" or order.active, but I'm sure everybody gets a point.)

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

2 participants