🔮 Sanity Create is here. Writing is reinvented. Try now, no developer setup

Is it possible to get a subset of an array in GROQ using `_key` of the initial and final element?

33 replies
Last updated: Sep 12, 2021
Hey folks, does anybody know if it’s possible to get via GROQ a subset of an array by having the
_key
of the initial and the final element?
I know I can do something like
*[_type == "post"]{body[_key match "KEY_HERE"]}
to get a single element, but does GROQ provide with a way to do something similar for a subset only?
Sep 12, 2021, 12:19 AM
Does it need to be based on a
_key
? You can use element access traversals (
[0]
and
[-1]
) to get the first and last items of the array.

*[_type == 'post']{
  'first': body[0],
  'last': body[-1]
}
Sep 12, 2021, 12:32 AM
user A
thanks for the quick response, pal! I want to be able to extract a subset of portable text blocks for certain cases, so I think
_key
is the only way to identify those, right?
Sep 12, 2021, 12:34 AM
This might not be possible with GROQ, in which case I would defer to just filter it in my code. Should be fine, was just looking to avoid the overhead on client side.
Sep 12, 2021, 12:35 AM
Your snippet is great (I could even use
_key
there to identify proper first and last), but is there any way to get the in between body blocks?
Sep 12, 2021, 12:37 AM
'others': body[_key != ^.body[0]._key && _key != ^.body[-1]._key]
Sep 12, 2021, 12:39 AM
Right, but imagine that my subset goes from the second element of the array to the second-last element. With that query, I would get the first and the last in
others
too, right?
Sep 12, 2021, 12:44 AM
I’m kinda looking for something that works as a magical within those two keys, but I recognize that I might be asking for too much 😅
Sep 12, 2021, 12:45 AM
I’m kinda looking for something that works as a magical within those two keys, but I recognize that I might be asking for too much 😅
Sep 12, 2021, 12:45 AM
Actually, the method above isn’t needed. You would just do
body[1..-2]
.
Sep 12, 2021, 12:45 AM
Ohh, so you mean you have two keys and want to know what’s between them?
Sep 12, 2021, 12:46 AM
yup
Sep 12, 2021, 12:46 AM
Okay, thanks. I follow you now. I’ll have to think about that.
Sep 12, 2021, 12:46 AM
I might hack it by storing position rather than key and using what you proposed.
Sep 12, 2021, 12:46 AM
but I thought
_key
might be a bit more convenient in case I change the content later 🙂
Sep 12, 2021, 12:47 AM
I think there might be a limitation due to the fact that slices need to take integers (they can’t use params, etc.).
Sep 12, 2021, 12:47 AM
is there any way I can get the position based on
_key
before doing
body[1..-2]
?
Sep 12, 2021, 12:48 AM
Yeah, I think you’re on to something. And yes, you’re also correct that it may be a bit inconvenient when content changes.
Sep 12, 2021, 12:48 AM
As I said at the beginning of the thread, I recognize that I might be asking for GROQ to be too smart, and that might mean too expensive queries.
Sep 12, 2021, 12:49 AM
Might be cheaper to just bring the entire body and filter it on JS, don’t you think? It’s just a JSON object after all.
Sep 12, 2021, 12:50 AM
Might be cheaper to just bring the entire body and filter it on JS, don’t you think? It’s just a JSON object after all.
Sep 12, 2021, 12:50 AM
user A
I just made a test and added a block of text above the one I was referencing to, and now the old
_key
is referencing that new element. So I don’t think storing
_key
s would be any different than just storing positions.
Sep 12, 2021, 12:54 AM
user A
I just made a test and added a block of text above the one I was referencing to, and it changed the
_key
to that first element. So I don’t think storing
_key
would be any different than just storing positions.
Sep 12, 2021, 12:54 AM
Ahh, so the first array item got its content replaced?
Sep 12, 2021, 12:55 AM
I added a paragraph on top of the paragraph I was pointing to. New paragraph
_key
has the value of the old one. So
_key
is not stable enough for me to trust in that way.
Sep 12, 2021, 12:58 AM
I added a paragraph on top of the paragraph I was pointing to. New paragraph
_key
has the value of the old one. So
_key
is not stable enough for me to trust in that way.
Sep 12, 2021, 12:58 AM
I’m thinking about adding a special block type that could act as a marker while doing the JSON to content transformation.
Sep 12, 2021, 12:58 AM
still, figuring out how to get the in between content with GROQ remains as an unsolved challenge. 😅
Sep 12, 2021, 12:59 AM
Don’t worry – I’ll be lying in bed thinking about it. 😆
Sep 12, 2021, 1:01 AM
hahaha sorry for doing that to you, thanks so much for helping out, you rock.
Sep 12, 2021, 1:02 AM
Don’t be! I love questions like this.
Sep 12, 2021, 1:02 AM
The point of the entire thing is that I want to be able to dynamically get subsets of a post from other posts.
Sep 12, 2021, 1:02 AM
And since Sanity is the only headless CMS that provides a sort of ID for each block (the
_key
), I figured it was a good experiment to try out!
Sep 12, 2021, 1:03 AM
As an alternative, and since I’m using Next.js, I think I’m gonna fetch linked posts at build time and build those subsets there.
Sep 12, 2021, 1:04 AM

Sanity– build remarkable experiences at scale

Sanity is a modern headless CMS that treats content as data to power your digital business. Free to get started, and pay-as-you-go on all plans.

Was this answer helpful?