gjson icon indicating copy to clipboard operation
gjson copied to clipboard

How to add multiple path conditions

Open nirenrc opened this issue 4 years ago • 5 comments

Hello

I am looking for way to input multiple path conditions to gjson.Get API. I used https://gjson.dev/ for verifying paths; unfortunately results are not as expected Input Path friends.#[last==Murphy][first==Craig]# Actual Result: {"first": "Dale", "last": "Murphy", "age": 44, "nets": ["ig", "fb", "tw"]} Expected Result: no output

Can you please explain how to provide multiple matching conditions?

Thanking You

Niren

nirenrc avatar Feb 21 '20 01:02 nirenrc

You can use the pipe character to chain a new path to the result of the first path:

friends.#(last=="Murphy")#|#(first=="Dale")#

tidwall avatar Feb 21 '20 17:02 tidwall

Thank You.

I missed pipe (|) output. I have another question on retrieving entire record post matching conditions of internal child nodes. I try to build path using pipe unfortunately, receiving incorrect results. For below extended model, like to match.

  • (first == Dale)
  • (last == Murphy)
  • (cars.make.name == Audi)
  • (models,name==A11)

Expected result: No output (model name A11 do not exists)

Input Json:

{ "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"], "cars":{"make":[{"name":"Audi","models":[{"name":"A1","year":1995},{"name":"A2","year":1996}]},{"name":"BMW","models":[{"name":"B1","year":1995},{"name":"B2","year":1996}]}]}}, {"first": "Roger", "last": "Craig", "age": 68, "nets": ["fb", "tw"], "cars":{"make":[]}}, {"first": "Jane", "last": "Murphy", "age": 47, "nets": ["ig", "tw"], "cars":{"make":[{"name":"Chevy","models":[{"name":"C1","year":2001}]}]}} ] }

Input Path:

friends.@this.#(last==Murphy)#|@this.#(first==Dale)#|@this.#(cars.make.#(name==Audi)#|@this.#(models.#(name==A11)#)#)

Result:

{"first": "Dale", "last": "Murphy", "age": 44, "nets": ["ig", "fb", "tw"], "cars":{"make":[{"name":"Audi","models":[{"name":"A1","year":1995},{"name":"A2","year":1996}]},{"name":"BMW","models":[{"name":"B1","year":1995},{"name":"B2","year":1996}]}]}}

What could be correct path?

Thanking You

Niren

nirenrc avatar Feb 24 '20 05:02 nirenrc

Here's a path that will work.

friends|#(last=Murphy)#|#(first=Dale)#|#.cars.make|#.#(name=Audi)#|#.#.models|#.#.#(name=A1)#|0.0.0

I'll break it up into steps delimited by the | character.

  1. friends
  2. #(last=Murphy)#
  3. #(first=Dale)#
  4. #.cars.make
  5. #.#(name=Audi)#
  6. #.#.models
  7. #.#.#(name=A1)#
  8. 0.0.0

Starting with this input:

{
"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"], "cars":{"make":[{"name":"Audi","models":[{"name":"A1","year":1995},{"name":"A2","year":1996}]},{"name":"BMW","models":[{"name":"B1","year":1995},{"name":"B2","year":1996}]}]}},
{"first": "Roger", "last": "Craig", "age": 68, "nets": ["fb", "tw"], "cars":{"make":[]}},
{"first": "Jane", "last": "Murphy", "age": 47, "nets": ["ig", "tw"], "cars":{"make":[{"name":"Chevy","models":[{"name":"C1","year":2001}]}]}}
]
}

friends

[
{"first": "Dale", "last": "Murphy", "age": 44, "nets": ["ig", "fb", "tw"], "cars":{"make":[{"name":"Audi","models":[{"name":"A1","year":1995},{"name":"A2","year":1996}]},{"name":"BMW","models":[{"name":"B1","year":1995},{"name":"B2","year":1996}]}]}},
{"first": "Roger", "last": "Craig", "age": 68, "nets": ["fb", "tw"], "cars":{"make":[]}},
{"first": "Jane", "last": "Murphy", "age": 47, "nets": ["ig", "tw"], "cars":{"make":[{"name":"Chevy","models":[{"name":"C1","year":2001}]}]}}
]

#(last=Murphy)#

[
{"first": "Dale", "last": "Murphy", "age": 44, "nets": ["ig", "fb", "tw"], "cars":{"make":[{"name":"Audi","models":[{"name":"A1","year":1995},{"name":"A2","year":1996}]},{"name":"BMW","models":[{"name":"B1","year":1995},{"name":"B2","year":1996}]}]}},
{"first": "Jane", "last": "Murphy", "age": 47, "nets": ["ig", "tw"], "cars":{"make":[{"name":"Chevy","models":[{"name":"C1","year":2001}]}]}}
]

#(first=Dale)#

[
{"first": "Dale", "last": "Murphy", "age": 44, "nets": ["ig", "fb", "tw"], "cars":{"make":[{"name":"Audi","models":[{"name":"A1","year":1995},{"name":"A2","year":1996}]},{"name":"BMW","models":[{"name":"B1","year":1995},{"name":"B2","year":1996}]}]}}
]

#.cars.make

[[
{"name":"Audi","models":[{"name":"A1","year":1995},{"name":"A2","year":1996}]},
{"name":"BMW","models":[{"name":"B1","year":1995},{"name":"B2","year":1996}]}
]]

#.#(name=Audi)#

[[
{"name":"Audi","models":[{"name":"A1","year":1995},{"name":"A2","year":1996}]}
]]

#.#.models

[[[
{"name":"A1","year":1995},
{"name":"A2","year":1996}
]]]

#.#.#(name=A1)#

[[[{"name":"A1","year":1995}]]]

0.0.0

{"name":"A1","year":1995}

You'll notice that this approach will retain the correct array levels until the last 0.0.0, which then extracts the element.

Another possible path is:

friends.#(last=Murphy)#|#(first=Dale).cars.make.#(name=Audi).models.#(name=A1)

This one does not retain the array depth.

tidwall avatar Feb 27 '20 22:02 tidwall

Thank You

Its clear & detailed answer.

Actually, I also need to know entire "friends" object that match above condition allowing me to get other details of friend object like age, nets etc.

What would be path?

I could use below path, is this correct way? I think doing below may impact performance as frequent access to "@this", is my understanding correct?

Path:

friends.@this.#(last==Murphy)#|@this.#(first==Dale)#|@this.#(cars.make)#|@this.#(cars.make.#(name==Audi))#|@this.#(cars.make.#(models))#|@this.#(cars.make.#(models.#(name==A1)))#

Result:

[{"first": "Dale", "last": "Murphy", "age": 44, "nets": ["ig", "fb", "tw"], "cars":{"make":[{"name":"Audi","models":[{"name":"A1","year":1995},{"name":"A2","year":1996}]},{"name":"BMW","models":[{"name":"B1","year":1995},{"name":"B2","year":1996}]}]}}]

Thanking You

Niren

nirenrc avatar Mar 02 '20 17:03 nirenrc

Hello

As you can refer from my previous comment note. I like to know parent node details when matching child path

In above case I would like to have

Match Conditions

  • (first == Dale)
  • (last == Murphy)
  • (cars.make.name == Audi)
  • (models,name==A1)

Returning

[{
		"first": "Dale",
		"last": "Murphy",
		"age": 44,
		"nets": ["ig", "fb", "tw"],
		"cars": {
			"make": [{
					"name": "Audi",
					"models": [{
							"name": "A1",
							"year": 1995
						}
					]
				}
			]
		}
	}
]

How to achieve this? What could be path?

Thanking You

Niren

nirenrc avatar Mar 02 '20 22:03 nirenrc