Athina Gavriilidou
Athina Gavriilidou

Reputation: 11

jsoniq - empty() function to determine if attribute is present

I use try.zorba.io My code (simplified) is:

        jsoniq version "1.0";
        let $tweets :=

    [
    {
    "id" : 1,
        "user" : {
        "id" : 1111,
        "screen_name" : "Bobby"
      }
    }, 
    {
      "id" : 2,
      "user" : {
        "id" : 1111,
        "screen_name" : "Bobby"
      }
    }, 
    {
      "id" : 3,
      "user" : {
        "id" : 2222,
        "screen_name" : "Greg"
      }
    }, 
    {
      "id" : 4,
      "user" : {
        "id" : 3333,
        "screen_name" : "Tom"
      }
    }
    ]

let $users :=
[
{
  "screen_name" : "Julie",
  "id" : 4444
}, {
  "screen_name" : "Tom",
  "id" : 3333
}, {
  "screen_name" : "Greg",
  "id" : 2222
}, {
  "screen_name" : "Barb",
  "id" : 5555
}, {
  "screen_name" : "Bobby",
  "id" : 1111
}, {
  "screen_name" : "Yall",
  "id" : 6666
}
]

I am trying to figure out the "screen_name" of all $users who don't have any $tweets. I think I have to use the empty(s) function somehow, but I don't know how. Here is my effort so far (but it doesn't work, my result is empty):

for $t in members($tweets)
for $u in members($users)
for $r in members($users)
where $u."id" eq $t."user"."id"
where  empty($r)
return $u."screen_name"

Any advice?

Upvotes: 1

Views: 294

Answers (1)

Ghislain Fourny
Ghislain Fourny

Reputation: 7279

You need a nested loop to compute the tweets for each user and bind them with a variable. Once these tweets are stored in a variable, you can filter with the empty function, like so (tested on try.zorba.io):

...
for $u in members($users)
let $tweets :=
  for $t in members($tweets)
  where $u."id" eq $t."user"."id"
  return $t
where  empty($tweets)
return $u."screen_name"

Note that try.zorba.io is currently running on Zorba 2.9, which is an older version. The stable, mature version of JSONiq is shipped with the latest Zorba 3.0, which you can download.

With Zorba 3.0, the query can be improved like so:

...
let $tweeting-user-ids := distinct-values($tweets[].user.id)
for $user in $users[]
where not $user.id = $tweeting-user-ids
return $user.screen_name

Upvotes: 0

Related Questions