Skip to content
New issue

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

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

Already on GitHub? # to your account

[ENHANCEMENT]: Allow array of strings in "GraphQL" variable in DQL #9118

Open
amaster507 opened this issue Jul 27, 2024 · 1 comment
Open
Labels
kind/enhancement Something could be better.

Comments

@amaster507
Copy link
Contributor

amaster507 commented Jul 27, 2024

Use case and current behavior

Syntax Examples (using default values):

  • query title($name: string = "Bauman") { ... }
  • query title($age: int = "95") { ... }
  • query title($uids: string = "0x1") { ... }
  • query title($uids: string = "[0x1, 0x2, 0x3]") { ... }. The value of the variable is a quoted array.

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"].

This list syntax only works with uids. I don't even know why the example ["13", "14"] is in the docs because those are not hexidecimal uids, and it just adds confusion thinking this feature is already implemented.

I can do:

const query = `
    query q($uids: string){
        items(func: uid($uids)) {
            uid
            srcId
        }
    }
`;

const req = {
  query,
  variables: {
    "$uids": "[0x9a, 0x9b]",
  }
};

But I can't do:

const query = `
    query q($srcIds: string){
        items(func: eq(srcId, $srcIds)) {
            uid
            srcId
        }
    }
`;

const req = {
  query,
  variables: {
    "$srcIds": "[\"25\", \"26\"]",
  }
};

Alternatively, when I want to query for a list of items not a uid, I have to dynamically build a more complex query and variable list.

// imagine this is a dynamic list from an input
const srcIds = [25, 26];
const varList = srcIds.map((_, i) => `$srcId_${i}`);

const query = `
    query q(${varList.map(var => `${var}: string`).join(", ")}){
        items(func: eq(
            srcId,
            ${varList.join(", ")}
          )
        ) {
            uid
            srcId
        }
    }
`;

const req = {
  query,
  variables: Object.fromEntries(varList.map((var, i) => [var, `${srcIds[i]}`]))
};

Enhancement

It would be nicer to do this:

// imagine this is a dynamic list from an input
const srcIds = [25, 26];

const query = `
    query q($srcIds: string){
        items(func: eq(
            srcId,
            $srcIds
          )
        ) {
            uid
            srcId
        }
    }
`;

const req = {
  query,
  variables: {
    "$srcIds": `[${srcIds.map((id) => `"${id}"`)}]`
  }
};

Solution proposal

No response

Links to Discuss, RFC or previous Issues and PRs

https://discuss.dgraph.io/t/how-to-find-nodes-given-an-array-of-values/3316/7?u=amaster507

Links to examples and research

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

Additional Information

It would be best to support the syntax $srcIds: [string] but for now a quicker fix would just allow an array of strings/ints like the $uids: string accepts.

@amaster507 amaster507 added the kind/enhancement Something could be better. label Jul 27, 2024
@amaster507
Copy link
Contributor Author

There is a question what to do though if the query actually wants to find a string that is equal to what could be evaulated as an array. That is something that will need to be tested and allow a workaround. I know I used strings to store JSON values in Dgraph, and I am sure others do. What I am not sure though is if anyone is querying with eq on those strings. Maybe the better option would be to add the $srcIds: [string] to not break existing functionality of searching for json like strings with $srcIds: string

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
kind/enhancement Something could be better.
Development

No branches or pull requests

1 participant