gjson icon indicating copy to clipboard operation
gjson copied to clipboard

Filtering values based on null /empty field from a JSON

Open anair-stack opened this issue 3 years ago • 6 comments

Is it possible to search based on a value for being null or empty ? in other words when a value is not being set all and want to filter out null values

for example I would like to get all the people(first name) who do not have a last name like this name := gjson.Get(json, programmers.#(lastName="").firstName)

tried null.nil , "" does not work

Thanks Pt

anair-stack avatar Jan 23 '21 04:01 anair-stack

Try programmers.#(lastName==).firstName (must be in `)

emeng13 avatar Mar 24 '21 22:03 emeng13

Seems null not handled at all.

hotrush avatar Sep 02 '21 09:09 hotrush

@anair-stack did you find any workaround?

hotrush avatar Sep 02 '21 09:09 hotrush

I'm trying to query an empty array.

This seems to work: image

This doesn't: image

I would expect [["Empty"]]

Robert-M-Muench avatar Apr 02 '22 16:04 Robert-M-Muench

This works: #.friends.#(nets.# == [])#.first

Robert-M-Muench avatar Apr 02 '22 16:04 Robert-M-Muench

Another way is to use the ~ operator, which converts a value to a boolean before comparison. There's some information on how it works at the bottom of the section about queries

friends.#(nets.#==~true)#.first

nets.# gets the number of values in the nets array. ==~true auto converts that value to either true or false and does the comparison.

What's nice about this approach is that the ~ handle non-existent and null values as false.

Take this JSON for example:

{
  "name": {"first": "Tom", "last": "Anderson"},
  "age":37,
  "children": ["Sara","Alex","Jack"],
  "fav.movie": "Deer Hunter",
  "friends": [
    {"first": "Dale", "last": "Murphy", "age": 44, "nets": ["ig", "fb", "tw"]},
    {"first": "Roger", "last": "Craig", "age": 68, "nets": ["fb", "tw"]},
    {"first": "Empty", "last": "Craig", "age": 68, "nets": []},
    {"first": "Missing", "last": "Craig", "age": 68},
    {"first": "Jane", "last": "Murphy", "age": 47, "nets": ["ig", "tw"]}
  ]
}

With the tilde:

friends.#(nets.#==~true)#.first     =>  ["Dale","Roger","Jane"]
friends.#(nets.#==~false)#.first    =>  ["Empty","Missing"]

Without the tilde, the nets must be an actual array. Otherwise it can be compared to anything because net.# is considered non-existent.

friends.#(nets.#==[])#.first        =>  ["Empty"]
friends.#(nets.#==0)#.first         =>  ["Empty"]
friends.#(nets.#>0)#.first          =>  ["Dale","Roger","Jane"]

But if what you want it only return those that explicitly define nets as an array:

friends.#(nets.#==0)#.first         =>  ["Empty"]
friends.#(nets.#!=0)#.first         =>  ["Dale","Roger","Jane"]

tidwall avatar Apr 02 '22 17:04 tidwall