Advanced GROQ With Parent Scopes and Subqueries

John Lindquist
InstructorJohn Lindquist

Share this video with your friends

Send Tweet
Published 6 months ago
Updated 6 months ago

GROQ enables you to join together data in whatever format you want. Based on the dataset, sometimes the query needs to include a subquery where you must track which scope the query is running to be able to compare values against values in the parent scope. The parent scope can be accessed through the ^ so you know which scope the value belongs to.

Instructor: [0:00] Each Pokémon in our Pokédex has a type and weaknesses. Pokémon that have weaknesses of fire shouldn't fight against Pokémon that are fire type. Let's construct a query that can match up and compare these two nested arrays inside of each Pokémon. This is fairly Advanced. If you understand this query, I would say you have a great understanding of GROQ.

[0:28] First, we need to essentially construct a nested loop. Here's our first loop through all of the data, which prints out every result. Let's just take the first three off of this. This one gets pretty intensive. Then, to go through the root data again, we're going to create a matchup property. This will go through, like we've done before, every Pokémon.

[0:54] Now, the filter here is going to be pretty interesting, because we're going to count using the count function, and making sure that the count is greater than zero. What we need to count are the weaknesses of this scope, so the root scope here, which is an array of strings.

[1:15] We're going to compare that string, you've seen this @ symbol before, meaning that now this @ represents the string, weakness, whether it's the fire, or ice, or whatever, and we're going to check if that string is in. We need to walk up two scopes, because right now, we're in this scope and we want to walk up here, and then walk up to that root scope there.

[1:38] We'll go up one, up one, and check if that weakness is in that type of this iteration. We can't just start another root scope iteration here. We have to make sure we're checking against the values of this scope. If the weakness exists in this type, then this count will be greater than zero.

[2:01] We'll go ahead and run that. You can see, because we limited that to four, we'll have four results. Each has matchup on them, each of those with 46 results. Those 46 results are coming from here, whereas the 4 results you see here, with through 3, are coming from here.

[2:21] Now we have this scope, which is this, and the matchup scope, which is this. We can construct and project more data from that. We'll create a message, and this time, we're only going to lookup one scope to the name.

[2:39] The reason being, is that in this one, we're getting outside of the scope of weaknesses, and outside of this scope, up into this scope. In this one, we're only getting outside of this scope, up into this one, because we're no longer inside of the weaknesses.

[2:56] This name and this type, those are the same scopes. When we compare the weakness to the type, you can think we're looking at the name of that type that this is weak to. We'll say, name + versus + the name of the Pokémon in the current scope. We'll run this again and now we'll check our results. You can see we have these matchups with these messages.

[3:20] Let's go ahead and get all of the messages, and then all of the matchups, run it again. You can see we have some matchups, Bulbasaur versus Squirtle, and down and down and down with all these matchups of the types versus their weaknesses.

[3:34] If we look at Bulbasaur and Squirtle in our data, you can see that Bulbasaur is a grass-type. When we look at Squirtle, you'll see that Squirtle is weak against grass-types. If we look at Bulbasaur versus Wartortle -- we'll search for Wartortle -- you'll see Wartortle is weak against grass-types. Technically, in all these matchups, the one on the left has the advantage against the one on the right.

[3:59] Lastly, let's just go ahead and drop our order filter on there to get these nice and sorted, run it again, so that when we browse through this, Bulbasaur was first before, but then Charmander, Ivysaur, and then down and down and down, and we have some matchups based on types and weaknesses.