Filter by values where key is unknown - jsonpath

In the following JSON -
[
{
"This": "TRUE",
"is": "TRUE",
"a": "FALSE",
"test": "FALSE",
"json": "TRUE"
}
]
How do I get the result using Jayway JsonPath that filters out the key<>value pair where value is "TRUE" i.e. expected output:
[
{
"This": "TRUE",
"is": "TRUE",
"json": "TRUE"
}
]
I tried using the following query but it returned no data (null JSON) -
$.[?(#.* == 'TRUE')]
Is there a way to filter without specifying the key and only by determining what the value should be? I'm using a different platform to get this information and not using JavaScript or any other scripting language. Just need to determine the appropriate query that would help extract the required output.

Related

JSON path evaluation inside JSON path expression

I've got this very simple json :
{
"authors": [
{
"id": 1,
"name": "Douglas Adams"
},
{
"id": 2,
"name": "John Doe"
}
],
"books": [
{
"name": "The Hitchhiker's Guide to the Galaxy",
"author_id": 1
}
]
}
I would like to request the name of the author of "The Hitchhiker's Guide to the Galaxy".
I've tried this JSON path but it doesn't work:
$.authors[?(#.id == $.books[?(#.name == "The Hitchhiker's Guide to the Galaxy")].author_id)].name
All online tools I tried indicate a syntax error which seems due to the presence of a JSON path inside my filter.
Could anyone please help me figure out what's wrong and what is the right syntax?
Thanks!
When you running this filter
$.books[?(#.name == "The Hitchhiker's Guide to the Galaxy")].author_id
it returns an array instead of a value:
[
1
]
Syntax error occurs when you pass an array to compare with the value of id:
$.authors[?(#.id == {the array value}].author_id)].name
However, you may not be able to extract the value using JSONPath, depends on the language you are using. See Getting a single value from a JSON object using JSONPath

Can't get the desired properties via JsonPath evaluate method

I have a json schema that marks special properties in need of processing and I want to query those via JsonPath.Evaluate.
Here's a part of the schema to illustrate the issue
{
"type": "object",
"properties": {
"period": {
"description": "The period in which the rule applies",
"type": "object",
"properties": {
"start": {
"type": "string",
"format": "date-time"
},
"end": {
"type": "string",
"format": "date-time"
}
},
"required": [
"start"
],
"x-updateIndicatorProperties": [
"start"
]
},
"productType": {
"type": "string"
},
"x-updateIndicatorProperties": [
"productType"
]
}
}
I want to get the the JsonPath of the "x-updateIndicatorProperties" properties, so that I can then query the actual properties to process.
For this example, the expected result would be
[
"$['properties']['x-updateIndicatorProperties']",
"$['properties']['period']['x-updateIndicatorProperties']"
]
I've been trying for a while to get a JsonPath expression that would query these properties.
Currently I'm just iterating all properties and filter them manually :
"$..*"
I've also tried using :
$..['x-updateIndicatorProperties']
This works. But it returns a lot of duplicates. For the example above, I get 5 results instead of the expected 2. Can be demonstrated here : https://json-everything.net/json-path
Assuming I can't influence the schema itself, only the code that traverses it,
can anybody help with an expression to get the expected results or any other way to achieve the same outcome?
The stack is JsonPath 0.2.0, .net 6 and system.text.json.
This was a bug in the library when parsing paths that use a recursive descent (..) into a quoted-property-name selector (['foo']). So it would happen for any path in the form $..['foo'].
I've fixed the issue and released version 0.2.1.

AWS Step Functions: Filter an array using JsonPath

I need to filter an array in my AWS Step Functions state. This seems like something I should easily be able to achieve with JsonPath but I am struggling for some reason.
The state I want to process looks like this:
{
"items": [
{
"id": "A"
},
{
"id": "B"
},
{
"id": "C"
}
]
}
I want to filter this array by removing entries for which id is not in a specified whitelist.
To do this, I define a Pass state in the following way:
"ApplyFilter": {
"Type": "Pass",
"ResultPath": "$.items",
"InputPath": "$.items.[?(#.id in ['A'])]",
"Next": "MapDeployments"
}
This makes use of the JsonPath in operator.
Unfortunately when I execute the state machine I receive an error:
{
"error": "States.Runtime",
"cause": "An error occurred while executing the state 'ApplyFilter' (entered at the event id #8). Invalid path '$.items.[?(#.id in ['A'])]' : com.jayway.jsonpath.InvalidPathException: com.jayway.jsonpath.InvalidPathException: Space not allowed in path"
}
However, I don't understand what is incorrect with the syntax. When I test here everything works correctly.
What is wrong with what I have done? Is there another way of achieving this sort of filter using JsonPath?
According to the official AWS docs for Step Functions,
The following in paths are not supported # .. , : ? *
https://docs.aws.amazon.com/step-functions/latest/dg/amazon-states-language-paths.html

Using nested fields in the projection of a DynamoDB GSI

I've got a Dynamo table storing documents that look like this:
{
"guid": "<some UUID>"
"created_at": 1550778260030,
"display_name": "person",
"updated_at": 1550778260030,
"info": {
"locked": false,
"confirmed": true,
"deactivated": false,
"email": "person#example.com"
}
}
The table has a Global Secondary Index managed by Terraform defined as such:
global_secondary_index {
name = "display_name_index"
hash_key = "display_name"
projection_type = "INCLUDE"
non_key_attributes = [
"updated_at",
"info.email",
"created_at"
]
}
However when I query the table the info.email field isn't returned:
aws dynamodb query \
--table-name "accounts" \
--index-name "display_name_index" \
--key-condition-expression "display_name = :display_name" \
--expression-attribute-values '{":display_name":{"S":"person"}}'
{
"Count": 1,
"Items": [
{
"created_at": {
"N": "1550778260030"
},
"display_name": {
"S": "person"
}
"updated_at": {
"N": "1550778260030"
}
}
],
"ScannedCount": 1,
"ConsumedCapacity": null
}
If I change the non_key_attributes to include info it returns the full info blob just fine, and I can use a projection-expression of info.email to retrieve that field just fine:
{
"Count": 1,
"Items": [
{
"info": {
"M": {
"email": {
"S": "person#example.com"
}
}
}
}
],
"ScannedCount": 1,
"ConsumedCapacity": null
}
The Dynamo docs do specify that index keys have to be top-level, but they don't mention anything about non-key attributes in a projection having to be top-level. Therefore I'd assume that anything that works in a projection-expression should work in an index projection, but that seems to not be the case?
Am I doing something wrong with this index definition or the query? Or does Dynamo just not support nested non-key attributes as part of an index's projection?
In simple words nested attribute can not be used as a GSI projection. It is not supported in DDB yet.
I walked into the same thing. I see there are no answers jet to your question. Not sure I have the right answer, but maybe it can help you out.
First of all, I think it's very weird creating GSI the API allows you to add a projection of "info.email" (this will also visible on the index overview page) but can never be retrieved again.
I found out when creating a GSI you are stuck on the attributes you have provided.
On the other hand, creating LSI you can use the attributes you have provided while creating the LSI.
You can found a little about this in this document (search for "Projected Attributes"):
https://docs.amazonaws.cn/en_us/amazondynamodb/latest/developerguide/SecondaryIndexes.html
I hope you can do something with this info.

Firebase REST API filter not working

I am trying to learn how to make rest calls with firebase
I have the following but get no results,
('/cases.json?orderBy="case_status"&equalTo="live"')
if I remove the
?orderBy="case_status"&equalTo="live"'
I get all my results returned
('/cases.json?orderBy="$key"&limitToFirst=2')
also works
my firebase table is as follows
cases
-LFXvk9yY5c-O8yIdf8k
case_name: "Issue 1"
case_status: "live"
case_summary: "Problem with code"
contact: "Fred"
-LFXvk9yY5c-O8h45std
case_name: "Issue 2"
case_status: "complete"
case_summary: "Also problem with code"
contact: "Fred"
I also tried adding a rule as below but that didn't work either
{
"rules": {
".read": true,
".write": true,
".indexOn": "case_status"
}
}
Can anyone tell me why the filter doesn't work as from the docs looks like it should
Thanks
You have probably missed the following warning in the REST API documentation at https://firebase.google.com/docs/database/rest/retrieve-data
Add Indexing to your Firebase Realtime Database Rules: If you're using orderBy in your app, you need to define the keys you will be indexing on via the .indexOn rule in your Firebase Realtime Database Rules.
Your rules should look like:
{
"rules": {
".read": "true", //just an example, probably to adapt!!
".write": "true", //just an example, probably to adapt!!
"cases": {
".indexOn": "case_status"
}
}
}

Resources