dgraph icon indicating copy to clipboard operation
dgraph copied to clipboard

Support lists in query variables (Dgraph's GraphQL Variable)

Open F21 opened this issue 5 years ago • 18 comments

Experience Report

I often have queries where I want to match a list of things (similar to an IN query in SQL). For example:

{
  someQuery(func: eq(somePredicate, val1, val2){
    someField
  }
}

Often, these values come from user input and I want to pass these values to the query using query variables.

Effectively, this would allow a query like so:

query($vals: []string){
  someQuery(func: eq(somePredicate, $vals){
    someField
  }
}

What you wanted to do

I wanted to pass a list of values as a query variable into a query.

What you actually did

I had to create the query programmatically using string concatenation.

Why that wasn't great, with examples

Having to use string concatenation introduced a lot of noise into the code and the query was very unreadable.

Any external references to support your case

None.

F21 avatar Nov 06 '18 02:11 F21

Note: This seems duplicated of https://github.com/dgraph-io/dgraph/issues/2272 PS. Just a note.

MichelDiz avatar Dec 10 '18 00:12 MichelDiz

Hey @F21 , I gonna close this issue due duplicate. To keep just one issue tracking this, the 2272.

Anyway thanks for the care of having opened an issue for this.

Cheers.

MichelDiz avatar Feb 05 '19 23:02 MichelDiz

Well I'm reopening this due some changes and more info related to GraphQL standard.

The issue #2272 was solved, but it was specific for block arrays, with an example of payload with array. But it did not go deep into adding an array to the var type itself.

Now I see that this issue appears to be more specific for this case.

As Dgraph intends to get closer to GraphQL's standard. I believe this is a good feature for this. In GraphQL you can add arrays to the variables used in a Query. e.g:

{
  query: `
    query events ($containsId: [Int]) { 
     # the parse results  events(containsId: [1,2,3]) {
      events(containsId: $containsId) {
        id
        name
      }
    }
  `,
  variables: {
    containsId: [1,2,3]
  }
}

UPDATE:

Also there's an issue with Documentation that says about the possibility to use arrays for UID.

Check https://docs.dgraph.io/query-language/#graphql-variables

Testing in https://play.dgraph.io/ I can't put a list of UIDs to work as docs says.

Note If you want to input a list of uids as a GraphQL variable value, you can have the variable as string type and have the value surrounded by square brackets like ["13", "14"].

I've tested several combinations and none was successful as docs mention.

query q($name1:string = ["0x1878bd", "0x237702"]) {
   me(func: uid( $name1 )) {
    uid
    name@en
    director.film @filter(lt(initial_release_date, "1980-01-01"))  {
      initial_release_date
      name@en
    }
  }
}

"0x1878bd, 0x237702" are "Ridley Scott" and "Steven Spielberg" uids.

MichelDiz avatar Feb 14 '19 15:02 MichelDiz

This is similar to #2272 but it's in fact a different feature. The variable array (Gql) is not the same as the argument list. We would need to add support for arrays and convert them into argument list for this to work.

The uid list is not the same as the array in the variable. This is how it works:

{
   //            .... argument list ....
   me(func: uid( "0x1878bd", "0x237702" )) {
    uid
    name@en
    director.film @filter(lt(initial_release_date, "1980-01-01"))  {
      initial_release_date
      name@en
    }
  }
}

srfrog avatar Feb 15 '19 03:02 srfrog

The uid list is not the same as the array in the variable.

Yeah, I know. But the point is that the Docs indicates that it is possible to use array for UIDs with Graphql Vars. I have not found any way to make it work according to the "Note" from docs.

MichelDiz avatar Feb 15 '19 04:02 MichelDiz

Any update on this? I'd really like to be able to do

query docs($urls: [string]) {
  docs(func: eq(url, $urls)) {
    title
    desc
  }
}

but it sounds like it's not currently supported. Coming from the SQL world this seems like a very basic operation that should be supported.

d4l3k avatar Aug 07 '19 02:08 d4l3k

A year passed, any update on array support ? the current workaround is to use string interpolation in the client code

Sceat avatar Apr 10 '20 10:04 Sceat

+1

sanan-fataliyev avatar Apr 27 '20 06:04 sanan-fataliyev

Is there ever any plan to support this? Otherwise, I have to do a string replacement for my query...

ahctangU avatar Jun 02 '20 08:06 ahctangU

Please, vote for the issue. We like comments when they add use cases. If you are just "voting" please, thumbs up the issue itself.

PS. Nothing is decided yet.

MichelDiz avatar Jun 02 '20 18:06 MichelDiz

Until this is done, would you mind updating the docs here to say it's not possible: https://dgraph.io/docs/query-language/#uid ? I just bumped in to this issue as well.

dpkirchner avatar Jun 18 '20 18:06 dpkirchner

@dpkirchner not sure what you mean. This part of the docs isn't related to GraphQL Variables.

MichelDiz avatar Jun 18 '20 19:06 MichelDiz

@MichelDiz Sounds like I'm just confused. There's GraphQL variable queries and there's regular queries that look pretty similar, and you can't pass multiple GraphQL variables to uid() (you'll see "Only one GraphQL variable allowed inside uid function" which I include here as google bait).

I see now in the docs you linked: "Note If you want to input a list of uids as a GraphQL variable value, you can have the variable as string type and have the value surrounded by square brackets like ["13", "14"]." That's not exactly how it seems to work in my tests, at least when using dgraph-js. The way to query multiple uids is to concatenate an array of the hex uids into a single string that is wrapped with square brackets, like so:

query query($uids: string) {
  query(func: uid($uids)) {
    ...
  }
}
txn.queryWithVars(query, {vars: {
  $uids: '[' + uids.join(',') + ']'
}});

ultimately, $uids = '[0x123,0x456,0x789]' (no quotes in the array string, hex values).

I don't know what's really actionable here beyond, maybe, updating the "Note if you want ..." text.

dpkirchner avatar Jun 18 '20 20:06 dpkirchner

This works

query query($uids: string = "[0x1, 0x2, 0x3]") {
  query(func: uid($uids)) {
    uid
  }
}

so, what needs to change, and not confuse future users, is the uid part. I gonna add references about this there.

MichelDiz avatar Jun 18 '20 21:06 MichelDiz

This works

query query($uids: string = "[0x1, 0x2, 0x3]") {
  query(func: uid($uids)) {
    uid
  }
}

so, what needs to change, and not confuse future users, is the uid part. I gonna add references about this there.

that's a nice interim solution but the client shouldn't have to convert a list of uids to strings and concatenate, we should be able to have an input of type [string] or [uid]

vancouverwill avatar Jun 23 '20 15:06 vancouverwill

@vancouverwill that's still the objective of this issue. I was just trying to help dpkirchner. I have done the change in docs about this. Until we have list support on GraphQL Variables.

MichelDiz avatar Jun 23 '20 16:06 MichelDiz

@vancouverwill that's still the objective of this issue. I was just trying to help dpkirchner. I have done the change in docs about this. Until we have list support on GraphQL Variables.

great, thankyou

vancouverwill avatar Jun 24 '20 11:06 vancouverwill

Github issues have been deprecated. This issue has been moved to discuss. You can follow the conversation there and also subscribe to updates by changing your notification preferences.

drawing

minhaj-shakeel avatar Jul 20 '20 18:07 minhaj-shakeel