GROQ Query Joins - How to get the Name Value on a Reference

1 replies
Last updated: Mar 7, 2021
Hello Sanity friends I'm back working on my sanity project and I'm still super confused on how to do joins
I have a company, which I'm selecting, each company can be one of may types, engineering, jewellery, agriculture, etc

I'd like to get the
companyType
so I query:
*[_type == "companyType"]{
     ...
    }
Then I have the result:

"result":[13 items
0:{7 items
"_createdAt":"2021-01-07T19:44:08Z"
"_id":"35b2a9f0-8d0b-4037-8062-02571f2333a0"
"_rev":"fS8ElWyBEaytBQCJREP4yC"
"_type":"companyType"
"_updatedAt":"2021-01-07T19:44:08Z"
"name":"Energy"
"slug":{2 items
"_type":"slug"
"current":"energy"
}
}
So this name is
Energy
if I want to get the
companyType
name in another query (which should return an array) how do I do that? Here's an example company
"result":[2 items
0:{14 items
"_createdAt":"2021-03-07T11:09:25Z"
"_id":"a832b6ff-9922-486a-842a-f59a35917323"
"_rev":"3p8Css1F5fRljRvMHcTddx"
"_type":"company"
"_updatedAt":"2021-03-07T11:09:25Z"
"companyPhone":"01322779068"
"companyType":[1 item
0:{3 items
"_key":"b2727521e1cf"
"_ref":"39b7d789-f6e8-48f3-bc13-96e831008528"
"_type":"reference"
}
]
"companyUrl":"<https://shoppy.com>"
"county":{2 items
"_ref":"4682fc71-885e-47f7-acc8-1267b4fefd44"
"_type":"reference"
}
"description":"A shoppy shop"
"image":{2 items
"_type":"image"
"asset":{...}2 items
}
"name":"Shoppy Shop"
"slug":{2 items
"_type":"slug"
"current":"shoppy-shop"
}
"visible":true
}
I want to join the company
_ref
to the
companyType
_id
right?
I really can't get my head around how the language syntax works and am struggling to get the name value on a reference

Thanks in advance sorry for text wall!
AI Update

Great question! The syntax can definitely be confusing at first, but once you get it, it's really powerful. You're on the right track - you want to "dereference" those references to get the actual data.

The key is the arrow operator (->) in GROQ. This operator follows a reference and fetches the actual document data. Here's how to solve your specific problem:

For a single company with its type name:

*[_type == "company" && _id == "a832b6ff-9922-486a-842a-f59a35917323"]{
  name,
  companyPhone,
  companyType[]->{
    name
  }
}

The companyType[]-> syntax does two things:

  1. [] - iterates through the array of references
  2. -> - dereferences each reference to get the actual companyType document
  3. {name} - projects only the fields you want (in this case, just the name)

For all companies with their type names:

*[_type == "company"]{
  name,
  companyPhone,
  companyUrl,
  description,
  visible,
  companyType[]->{
    name,
    slug
  }
}

This will give you results like:

{
  "name": "Shoppy Shop",
  "companyPhone": "01322779068",
  "companyType": [
    {
      "name": "Energy",
      "slug": {"current": "energy"}
    }
  ]
}

If you just want the names as a flat array:

*[_type == "company"]{
  name,
  "companyTypeNames": companyType[]->name
}

This gives you:

{
  "name": "Shoppy Shop",
  "companyTypeNames": ["Energy"]
}

The reference access operator (->) documentation explains that it internally executes a subquery to fetch the referenced document by matching the _ref value to the _id of the target document - exactly what you described wanting to do!

Think of -> as saying "go fetch the document this reference points to" - it's GROQ's way of doing joins.

Show original thread
1 reply
*[_type == "company"]{
  ...,
  companyType[]->,
}
Or

*[_type == "company"]{
  ...,
  companyType[]->{
    _id,
    name,
    slug
  },
}

So the logic in the projection is:

companyType
&lt;= pick companyType field (which is an array of company types
[]
&lt;= traverse the array (this is the part that trips most people up at first)
->
 &lt;= join the
_ref
 by looking for a document that has it as an
_id

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?