3

I'm learning to code and now I am on the stage of a small pet project with Sanity as a CMS. Long story short, making an API I'm trying to fetch cocktails data with votes for the cocktails. The votes are stored within persons who voted:

GROQ query

*[
  _type == "cocktail" &&
    !(_id in path('drafts.**'))
 ] {
  name,
  _id,
    "votes" : *[_type == "person" && references(^._id)] {
    votes[] {
        score,
        "id": cocktail._ref
        }
    } 
}

which returns

[
  {
    "_id": "pdUGiuRzgLGpnc4cfx76nA",
    "name": "Cuba Libre",
    "votes": [
      {
        "votes": {
          "id": "pdUGiuRzgLGpnc4cfx76nA",
          "score": 2
        }
      },
      {
        "votes": {
          "id": "pdUGiuRzgLGpnc4cfx76nA",
          "score": 2
        }
      }
    ]
  },
  {
    "_id": "pdUGiuRzgLGpnc4cfxBOyM",
    "name": "The ERSH7",
    "votes": []
  }
]

As you can see, the merge provides embedded arrays of votes meanwhile I want sth like:

[{
  ...cocktail attributes...
  "votes" : [
    {score: 2, id: pdUGiuRzgLGpnc4cfx76nA},
    {score: 2, id: pdUGiuRzgLGpnc4cfx76nA}
  ]
 }
... more cocktails....
]

Trying to get this I modified the query:

*[
  _type == "cocktail" &&
    !(_id in path('drafts.**'))
 ] {
  name,
  _id,
    "votes" : *[_type == "person" && references(^._id)].votes[] {
        score,
        "id": cocktail._ref
    }
}

which should take a projection from every element of the votes arr. Unfortunately I get empty arrays:

[
{
  "_id": "pdUGiuRzgLGpnc4cfx76nA",
  "name": "Cuba Libre",
  "votes": [
    {},
    {}
  ]
}
...more cocktails
]

How can I achieve the desired result? Thank you for reading! Would appreciate any help!

2 Answers 2

3

Yes, had similar struggles with "flattening" the projections my self. I solved it with dot-syntax. Try just adding .votes on your first attempt:

*[
  _type == "cocktail" &&
  !(_id in path('drafts.**'))
]
{
  name,
  _id,
  "votes" : *[_type == "person" && references(^._id)] {
    votes[] {
      score,
      "id": cocktail._ref
    }
  }
  .votes
}

If this is correct, the whole query can be simplified but I'm not at the level, yet, where I can do that without testing against a similar set ,'-)

3

Actually, GROQ has syntax to flatten array starting from v2021-03-25

find this example:

{
  'nestedArray': [
    {'foo': [1,2,3,4,5]},
    {'foo': [6,7,8,9,10,11,12]},
    {'foo': [13,14,15]},
  ]
}{
  'stillNestedArray': @.nestedArray[].foo,
  'flatArray': @.nestedArray[].foo[]
}

Note the [] right after foo - this is what's flatten it

So the original query from the question should look like

*[
  _type == "cocktail" &&
    !(_id in path('drafts.**'))
 ] {
  name,
  _id,
    "votes" : *[_type == "person" && references(^._id)] {
    votes[] {
        score,
        "id": cocktail._ref
        }
    }.votes[] 
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.