← Back to list

Query JSON Fields in Big Query by Custom Function

Query Any Kind of Data in Big Query’s JSON Field even if you don’t know the keys name exactly or you are using dynamic keys so in this way…

Nikhivishwa · 2025-04-10 19:21 · 3 claps · 2.9 min read
#bigquery #bigquery-sql #functions-in-sql #json-sql #big-data-analytics
Open on Medium ↗
Wiki topics: GRW · Growth & Analytics 🔧 · Data Engineering

Query JSON Fields in Big Query by Custom Function

Query Any Kind of Data in Big Query’s JSON Field even if you don’t know the keys name exactly or you are using dynamic keys so in this way you can do it.

Step 1:

View the format / schema of JSON field, simply by SELECT Clause.

SELECT json_field FROM `mytable`

Sample Output:

{
  "json_field": {
    "user1": {
      "likes": [
        {
          "emoji": "👍",
          "comment": "nice guy"
        },
        {
          "emoji": "❤️",
          "comment": ""
        }
      ]
    },
    "user9": {
      "likes": [
        {
          "emoji": "😎",
          "comment": "ego"
        },
        {
          "emoji": "❤️",
          "comment": "engaging"
        }
      ]
    },
    "user45": {
      "likes": [
        {
          "emoji": "👍",
          "comment": "good"
        },
        {
          "emoji": "👌",
          "comment": ""
        }
      ]
    }
  }
}

In the above example we have a JSON field which stores the data of likes received by the user. And they are nested under the user id of providing user and for every user this data is different so we need a way that can extract these likes and user ids. And then we can perform join to get information about the providing users.

Step 2:

Now i am writing the logic in JavaScript for extracting the information from the JSON field.

const results = [];
try {
  const likesData = JSON.parse(data); // if json_field is stored as string

  for (const userId in likesData) {
    const user = likesData[userId];
    if (user?.likes) {
      for (const like of user.likes) {
        results.push({
          status: 'received',
          emaoji: like?.emoji,
          comment: like?.comment,
          givenBy: userId,
        });
      }
    }
  }
}catch(e){}

Now after getting my required format i can use this code inside my SQL Query to get the result, Let me show you how:

    CREATE TEMP FUNCTION flatten_likes(data STRING)
    RETURNS ARRAY<STRUCT<status STRING, emoji STRING, comment STRING, givenBy STRINGtKey STRING>>
    LANGUAGE js AS """
      const results = [];
      try {
        const likesData = JSON.parse(data);

        for (const userId in likesData) {
          const user = likesData[userId];
          if (user?.likes) {
            for (const like of user.likes) {
              results.push({
                status: 'received',
                emaoji: like?.emoji,
                comment: like?.comment,
                givenBy: userId,
              });
            }
          }
        }
      }catch(e){}
      return results;
    """;

    SELECT flatten_likes(json_field) AS likes
    FROM `mytable`;

The above Query will create a temporary function named flatten_likes(). And this function is used inside the query to extract the likes attribute value. The Sample output will be:

{
  "likes": [
    {
      "status": "received",
      "emoji": "👍",
      "comment": "nice guy",
      "givenBy": "user1"
    },
    {
      "status": "received",
      "emoji": "❤️",
      "comment": "",
      "givenBy": "user1"
    },
    {
      "status": "received",
      "emoji": "😎",
      "comment": "ego",
      "givenBy": "user9"
    },
    {
      "status": "received",
      "emoji": "❤️",
      "comment": "engaging",
      "givenBy": "user9"
    },
    {
      "status": "received",
      "emoji": "👍",
      "comment": "good",
      "givenBy": "user45"
    },
    {
      "status": "received",
      "emoji": "👌",
      "comment": "",
      "givenBy": "user45"
    }
  ]
}

Now i can use this likes array to perform join and get the more details of providing users like their name. So we will have a view as follows:

user name status emoji comment given_by provider_name

Step 3:

Finally joining this json_field with same table as it has the Recusrive Relationship. So the final query will be:

CREATE TEMP FUNCTION flatten_likes(data STRING)
    RETURNS ARRAY<STRUCT<status STRING, emoji STRING, comment STRING, givenBy STRINGtKey STRING>>
    LANGUAGE js AS """
      const results = [];
      try {
        const likesData = JSON.parse(data);

        for (const userId in likesData) {
          const user = likesData[userId];
          if (user?.likes) {
            for (const like of user.likes) {
              results.push({
                status: 'received',
                emaoji: like?.emoji,
                comment: like?.comment,
                givenBy: userId,
              });
            }
          }
        }
      }catch(e){}
      return results;
    """;

    SELECT u1.userId AS user, u1.name, l.status, l.emoji,
      l.comment, l.givenBy AS given_by, u2.name AS provider_name
    FROM `mytable` AS u1
    JOIN UNNEST(flatten_likes(json_field)) AS l
      ON l.givenBy != u1.userId
    JOIN `mytable` AS u2
      ON l.givenBy = u2.userId;

Sample Output:

[
  {
    "user": "user5",
    "name": "ravi",
    "status": "received",
    "emoji": "👍",
    "comment": "nice guy",
    "given_by": "user1",
    "provider_name": "sumit"
  },
  {
    "user": "user5",
    "name": "ravi",
    "status": "received",
    "emoji": "❤️",
    "comment": "",
    "givenBy": "user1",
    "provider_name": "sumit"
  },
  {
    "user": "user5",
    "name": "ravi",
    "status": "received",
    "emoji": "😎",
    "comment": "ego",
    "givenBy": "user9",
    "provider_name": "pankaj"
  },
  {
    "user": "user5",
    "name": "ravi",
    "status": "received",
    "emoji": "❤️",
    "comment": "engaging",
    "givenBy": "user9",
    "provider_name": "pankaj"
  },
  {
    "user": "user5",
    "name": "ravi",
    "status": "received",
    "emoji": "👍",
    "comment": "good",
    "givenBy": "user45",
    "provider_name": "keshav"
  },
  {
    "user": "user5",
    "name": "ravi",
    "status": "received",
    "emoji": "👌",
    "comment": "",
    "givenBy": "user45",
    "provider_name": "keshav"
  }
]

I Hope this article will help you. Let me know if you need any further clarification.


메타데이터
post_id
e3f214749c71
slug
query-json-fields-in-big-query-by-custom-function-e3f214749c71
url
https://medium.com/@nikhivishwa/query-json-fields-in-big-query-by-custom-function-e3f214749c71
canonical_url
https://medium.com/@nikhivishwa/query-json-fields-in-big-query-by-custom-function-e3f214749c71
author_url
https://medium.com/@nikhivishwa
status
ok
fetched_at
2026-07-14 12:33:16