Provide a way to replace an object with a single value

Moved from GitHub dgraph/2807

Posted by stefanfransen:

Hi, for my use case I’ve got images saved to products as an edge.
I can’t use string lists because I’m saving a hash with the image used for image based searches.
Often I need to only get the image URLs when retrieving a product, at the moment this adds an unnecessary object for every image.

Discussion with some interesting ideas by @MichelDiz

What you wanted to do

I want to get this output:

{
  "product": [
    {
      "name": "Bissell Multi-oppervlaktereiniger",
      "description": "De veelzijdige CrossWave stofzuigt, dweilt en helpt bij het drogen van vloeren. \n- zowel natte als droge reiniging \n- geen stofzak",
      "image": [
        "https://www.alternate.nl/p/450x450/n/ntzrza9k_30.jpg",
        "https://www.alternate.nl/p/450x450/1/1ss9a04z_30.jpg",
        "https://www.alternate.nl/p/450x450/9/9gsheq09_30.jpg"
      ]
    }
  ]
}

With the following query:

{
  product(func: uid(0x70980)) {
    name : <http://schema.org/name>
    description : <http://schema.org/description>
    image {
      url
    }
  }
}

What you actually did

This is the output I got.

{
  "product": [
    {
      "name": "Bissell Multi-oppervlaktereiniger",
      "description": "De veelzijdige CrossWave stofzuigt, dweilt en helpt bij het drogen van vloeren. \n- zowel natte als droge reiniging \n- geen stofzak",
      "image": [
        {
          "url": "https://www.alternate.nl/p/450x450/n/ntzrza9k_30.jpg"
        },
        {
          "url": "https://www.alternate.nl/p/450x450/1/1ss9a04z_30.jpg"
        },
        {
          "url": "https://www.alternate.nl/p/450x450/9/9gsheq09_30.jpg"
        }
      ]
    }
  ]
}

So at the moment I’m modifying this output of objects into a array of strings.

Why that wasn’t great, with examples

This adds extra unnecessary code.

Any external references to support your case

No references, think the reason for a function that minimizes the output is always a great addition

If this a feature more people are interested in I would love to open a PR for this.
Let me know what your thoughts are.

Stefan Fransen.

manishrjain commented :

This is tricky, because the behavior would have to be different if you ran this query instead:

{
  product(func: uid(0x70980)) {
    name : <http://schema.org/name>
    description : <http://schema.org/description>
    image {
      url, thumbnail
    }
  }
}

Because image would then have 2 fields, it would have to be a JSON map. So, I think it only increases code complexity – because depending upon how many fields were asked for, the user would need to switch how they parse the response. Either as a list of strings or as a list of objects.

campoy commented :

I do not think we should do this automatically, as @manishrjain mentions the behavior would change when used with url, thumbnail.

My proposal would be to use a special alias that would replace the current object with the value given.

So for instance, your query would be:

{
  product(func: uid(0x70980)) {
    name : "http://schema.org/name"
    description : "http://schema.org/description"
    image {
      .: url
    }
  }
}

By using the alias name . in .: url, you’d basically saying you want to replace the current object with the value on the right side.

So if image pointed to a single UID (not a list) you’d get:

{
  "product": [
    {
      "name": "Bissell Multi-oppervlaktereiniger",
      "description": "De veelzijdige CrossWave stofzuigt, dweilt en helpt bij het drogen van vloeren. \n- zowel natte als droge reiniging \n- geen stofzak",
      "image": "https://www.alternate.nl/p/450x450/n/ntzrza9k_30.jpg"
    }
  ]
}

And in the case where you have a list, you’d get:

{
  "product": [
    {
      "name": "Bissell Multi-oppervlaktereiniger",
      "description": "De veelzijdige CrossWave stofzuigt, dweilt en helpt bij het drogen van vloeren. \n- zowel natte als droge reiniging \n- geen stofzak",
      "image": [
        "https://www.alternate.nl/p/450x450/n/ntzrza9k_30.jpg",
        "https://www.alternate.nl/p/450x450/1/1ss9a04z_30.jpg",
        "https://www.alternate.nl/p/450x450/9/9gsheq09_30.jpg"
      ]
    }
  ]
}

as you wished.

What do you think of this proposal?