Eq list with val() does not return all matches

Moved from GitHub dgraph/5770

Posted by danielmai:

What version of Dgraph are you using?

v20.03.3

Have you tried reproducing the issue with the latest release?

Yes

What is the hardware spec (RAM, OS)?

Ubuntu Linux, Docker

Steps to reproduce the issue (command/config used to run Dgraph).

  1. Run Dgraph cluster

  2. Set the following schema with a string predicate:

    curl 'localhost:8080/alter' \
         -d 'name: string .'
    
  3. Run the following mutation

    curl 'localhost:8080/mutate?commitNow=true' \
         -H "Content-Type: application/json" \
         -d '{"set":[{"uid":"_:root","connects":[{"name": "A"},{"name":"B"}]}]}'
    
  4. Run the following query

    curl 'localhost:8080/query' \
         -H "Content-Type: application/graphql+-" \
         -d '
    {
      var(func: has(name)) {
        n as name
      }
    
      names(func: uid(n)) {
        name
      }
      nameA(func: eq(val(n), "A")) {
        name
      }
      nameB(func: eq(val(n), "B")) {
        name
      }
    
      q(func: eq(val(n), ["A", "B"])) {
        name
      }
    }'
    

Expected behaviour and actual result.

The actual query result is:

{
  "data": {
    "q": [
      {
        "name": "A"
      }
    ]
  }
}

The expected query result is that eq(val(n), ["A", "B"]) in the filter returns back both nodes A and B in the response:

{
  "data": {
    "q": [
      {
        "name": "A"
      },
      {
        "name": "B"
      }
    ]
  }
}

When running a query to get the individual blocks out, I see the queries for individual matches to return back the data as expected:

Query

curl 'localhost:8080/query' \
        -H "Content-Type: application/graphql+-" \
        -d '
   {
     var(func: has(name)) {
       n as name
     }

     names(func: uid(n)) {
       name
     }
     nameA(func: eq(val(n), "A")) {
       name
     }
     nameB(func: eq(val(n), "B")) {
       name
     }

     q(func: eq(val(n), ["A", "B"])) {
       name
     }
   }'

Response

{
  "data": {
    "names": [
      {
        "name": "A"
      },
      {
        "name": "B"
      }
    ],
    "nameA": [
      {
        "name": "A"
      }
    ],
    "nameB": [
      {
        "name": "B"
      }
    ],
    "q": [
      {
        "name": "A"
      }
    ]
  }
}

Is this still an issue? If so is there any idea of when it might be fixed?

I was trying out the runnable examples in the documentation https://dgraph.io/docs/query-language/functions/#equal-to and the example will run but doesn’t appear to return the “correct” results. I’ve tried several queries to try and confirm. I’m new to DQL so please let me know if I’m missing some syntax.

Example:

{
  steve as var(func: allofterms(name@en, "Steven")) {
    films as count(director.film)
  }

  stevens(func: uid(steve)) @filter(eq(val(films), [1,2,3])) {
    name@en
    numFilms : val(films)
  }
}

Results (truncated)

{
  "data": {
    "stevens": [
      {
        "name@en": "Steven Wilsey",
        "numFilms": 1
      },
      {
        "name@en": "Steven Bratter",
        "numFilms": 1
      },
      {
        "name@en": "Steven Saussey",
        "numFilms": 1
      },
      {
        "name@en": "Steven Ray Morris",
        "numFilms": 1
      },
      {
        "name@en": "Steven Bram",
        "numFilms": 1
      },
      {
        "name@en": "Steven Paul Contreras",
        "numFilms": 1
      },
      {
        "name@en": "Steven Pravong",
        "numFilms": 1
      },
      {
        "name@en": "Steven Danz",
        "numFilms": 1
      },

Modified Example to sort 3’s to the top but no 3’s

{
  steve as var(func: allofterms(name@en, "Steven")) {
    films as count(director.film)
  }

  stevens(func: uid(steve), orderdesc: val(films)) @filter(eq(val(films), [1,2,3])) {
    name@en
    numFilms : val(films)
  }
}

Results (truncated):

{
  "data": {
    "stevens": [
      {
        "name@en": "Steven Wilsey",
        "numFilms": 1
      },
      {
        "name@en": "Steven Bratter",
        "numFilms": 1
      },
      {
        "name@en": "Steven Saussey",
        "numFilms": 1
      },
      {
        "name@en": "Steven Ray Morris",
        "numFilms": 1
      },
      {
        "name@en": "Steven Bram",
        "numFilms": 1
      },
      {
        "name@en": "Steven Paul Contreras",
        "numFilms": 1
      },
      {
        "name@en": "Steven Pravong",
        "numFilms": 1
      },
      {
        "name@en": "Steven Danz",
        "numFilms": 1
      },

Modified example with less than equal instead which does return 3’s

{
  steve as var(func: allofterms(name@en, "Steven")) {
    films as count(director.film)
  }

  stevens(func: uid(steve), orderdesc: val(films)) @filter(le(val(films), 3)) {
    name@en
    numFilms : val(films)
  }
}

Results (truncated):

{
  "data": {
    "stevens": [
      {
        "name@en": "Steven Pearl",
        "numFilms": 3
      },
      {
        "name@en": "Steven Esteb",
        "numFilms": 3
      },
      {
        "name@en": "Steven Paul",
        "numFilms": 3
      },
      {
        "name@en": "Steven Ayromlooi",
        "numFilms": 3
      },
      {
        "name@en": "Steven Tanenbaum",
        "numFilms": 3
      },
      {
        "name@en": "Mark Steven Bosko",
        "numFilms": 3
      },
      {
        "name@en": "Steven Feldman",
        "numFilms": 3
      },
      {
        "name@en": "Mark Steven Grove",
        "numFilms": 3
      },