Accessing grandparent object in GROQ query with ^ operator

23 replies
Last updated: Oct 29, 2021
Hi for some reasons I'm trying to get access to grandparent object but
^.^
is not working šŸ˜ž
*[_type == 'post' && slug.current == $slug]{
  children[]->{
    'post': ^.^
  }
}
Except the
@
and
^
operators, I can't find anything that could do the job šŸ˜•
AI Update

I understand the frustration! Unfortunately, ^.^ doesn't work after the dereference operator (->) in your query, though I should be upfront that the official documentation doesn't explicitly explain why this limitation exists.

What we do know from the parent operator documentation is that ^ traverses up through projection scopes and can be chained as ^.^ for grandparent access. However, the reference access operator (->) internally executes a subquery to fetch the referenced document, which appears to create a context where the parent scope chain is no longer accessible—though the exact mechanics of this aren't fully documented.

What's Happening in Your Query

In your query:

*[_type == 'post' && slug.current == $slug]{
  children[]->{
    'post': ^.^  // This doesn't work
  }
}

The dereference creates a new query context for the referenced document, and the ^ operator can't traverse back through that boundary based on observed behavior.

Working Solutions

Option 1: Capture the parent before dereferencing

*[_type == 'post' && slug.current == $slug]{
  ...,
  children[]{
    'childData': @->,
    'post': ^
  }
}

Here, ^ inside the children[] projection (before dereferencing) correctly refers to the parent post document.

Option 2: Access specific fields before dereferencing

*[_type == 'post' && slug.current == $slug]{
  _id,
  title,
  'enrichedChildren': children[]{
    'ref': @,
    'child': @->,
    'parentId': ^._id,
    'parentTitle': ^.title
  }
}

Option 3: Restructure to keep post and children as siblings

*[_type == 'post' && slug.current == $slug][0]{
  'post': @,
  'children': children[]->
}

Option 4: Use a nested structure

*[_type == 'post' && slug.current == $slug] {
  'parentPost': @,
  'childrenWithData': children[]->
}

The practical workaround is to capture what you need from the parent scope before you dereference. Option 1 is usually the cleanest approach—it maintains access to the parent post while still getting your dereferenced child data.

Show original thread
23 replies
First, which API version are you using? You’ll need
v2021-03-25
or later to get the right behaviour.
Secondly, with that newer version,
^.
along should give you what you want, i.e. the parent scope.
I'm using the
2021-10-04
API version.
First, which API version are you using? You’ll need
v2021-03-25
or later to get the right behaviour.
Secondly, with that newer version,
^.
along should give you what you want, i.e. the parent scope.
I'm using the
2021-10-04
API version.
Ok, good. Have you triedĀ 
^
instead of
^.^
?
Yep, I tried a lot of things. In every scenario, it's not working. Even something like
^.^.^.^
Testing on Vision Playground and my code it's not working.But strangely on
https://groq.dev , it is
That’s because groq.dev uses a different JS implementation of GROQ
// JSON
[
  {
    "title": "parent",
    "_type": "post",
    "children": [
      {
        "_key": "5678",
      	"_type": "reference",
      	"_ref": "1234"
      }
    ]
  },
  {
    "_id": "1234",
    "_type": "child",
    "title": "Child"
  }
]

// request
*[_type == 'post']{
  ...,
  children[]->{
    'post': ^
  }
}

// result
[
  {
    "title": "parent",
    "_type": "post",
    "children": [
      {
        "post": {
          "title": "parent",
          "_type": "post",
          "children": [
            {
              "_key": "5678",
              "_type": "reference",
              "_ref": "1234"
            }
          ]
        }
      }
    ]
  }
]
Yeah I was expecting something like that šŸ˜•
This works fine for me (with just
^
). Are you sure you’re using
v2021-10-04
?
Ok sorry about this, this is totally working in my code but not on Vision Playground (I don't know how to check the version of the playground).
Sorry for the stupid question, long day for me
Do you mean the Vision plugin inside the Studio?
Yep
If so, it might have a dropdown. It’s been a while since I used it.
Studio projects still default to v1, AFAIK. You can specify the version in
sanity.json
.
(I’m not a Studio dev, so I’m not 100% sure here)
Oh damn !
Thanks for all.Yep you can choose the API version in the Studio, I wasn't looking at the right place ^^'
šŸ™‚
Glad you got it working!
Haha me too, thanks again

Sanity – Build the way you think, not the way your CMS thinks

Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.

Was this answer helpful?