deleting content from a particular collection - json

I have a JSON document like
{
"branch": [
{
"section": [
{
"sub": "edc",
"time": "one hour",
"frequency": "3"
},
{
"sub": "bee",
"time": "two hours",
"frequency": "4"
}
]
},
{
"section": [
{
"sub": "ss",
"time": "one hour",
"frequency": "2"
},
{
"sub": "ms",
"time": "two hours",
"frequency": "5"
}
]
}
]
}
Now I want to delete
{
"sub": "edc",
"time": "one hour",
"frequency": "3"
}
using "sub":"edc" from the following collection
I want the query to perform changes in mongo db

You need to use $pull, although i've not done it with nested array.
See http://docs.mongodb.org/manual/reference/operator/pull/
Something like: (but you'll need to test it)
db.yourcoll.update( { "branch.section.sub": 'edu' }, { $pull: { "branch.section.sub": 'edu' } } )
This is a similar question:
How to remove an element from a doubly-nested array in a MongoDB document

Related

PayPal JSON format updating order

I know I am close on this, the error messages are getting nicer. Currently, I can call a similar call to update the seller's email no issue via Postman currently, working on updating the amount and associated objects. Something in my request format is off.
Is my breakdown section in the correct location? The amount_breakdown documentation looks like it is on same level as value and currency_code, so does it need to move into that section.
Here's my request JSON via Postman:
[
{
"op": "replace",
"path": "/purchase_units/#reference_id=='default'/amount",
"value": {
"currency_code": "CAD",
"value": "2",
"amount": {
"currency_code": "CAD",
"value": "2",
"breakdown": {
"item_total": {
"currency_code": "CAD",
"value": "2"
},
"tax_total": {
"value": "0",
"currency_code": "CAD"
}
}
},
"items": [
{
"name": "First Product Name",
"description": "Optional descriptive text..",
"unit_amount": {
"currency_code": "CAD",
"value": "2"
},
"tax": {
"value": "0",
"currency_code": "CAD"
},
"quantity": "1"
}
]
}
}
]
RESPONSE:
{
"name": "UNPROCESSABLE_ENTITY",
"details": [
{
"field": "/purchase_units/#reference_id=='default'/amount/breakdown/item_total",
"location": "body",
"issue": "ITEM_TOTAL_REQUIRED",
"description": "If item details are specified (items.unit_amount and items.quantity) corresponding amount.breakdown.item_total is required."
}
],
"message": "The requested action could not be performed, semantically incorrect, or failed business validation.",
"debug_id": "acecd3643c994",
"links": [
{
"href": "https://developer.paypal.com/docs/api/orders/v2/#error-ITEM_TOTAL_REQUIRED",
"rel": "information_link",
"method": "GET"
}
]
}
Thanks for any help!
Different variations of objects.
I can get the other PATCH operation working no issue but it is much simpler in object structure
There should be no amount key under the /amount path, and the items array does not belong at that /amount path either.

JSONPath for Root element

I'm using JSONPath in AWS Step Functions (playground: Parameters tab).
In this example if we have a JSON input:
{
"movies": [
{
"genre": "crime",
"director": "Quentin Tarantino",
"title": "Reservoir Dogs",
"year": 1992
},
{
"genre": "action",
"director": "Brian De Palma",
"title": "Mission: Impossible",
"year": 1996,
"staring": [
"Tom Cruise"
]
}
],
"metadata": {
"lastUpdated": "2020-05-27T08:00:00.000Z"
},
"stringJson": "{\"arr\": [1, 2, 3, 4, 5], \"bool\": true, \"null\": null, \"number\": 1}"
}
and parameters like this:
{
"test.$": "$.metadata"
}
we would get this output:
{
"test": {
"lastUpdated": "2020-05-27T08:00:00.000Z"
}
}
while I would like to get
{
"lastUpdated": "2020-05-27T08:00:00.000Z"
}
or even better, say all but one:
{
"movies": [
{
"genre": "crime",
"director": "Quentin Tarantino",
"title": "Reservoir Dogs",
"year": 1992
},
{
"genre": "action",
"director": "Brian De Palma",
"title": "Mission: Impossible",
"year": 1996,
"staring": [
"Tom Cruise"
]
}
],
"metadata": {
"lastUpdated": "2020-05-27T08:00:00.000Z"
}
}
How do I put an element (or all elements) in the root?
I tried parameters like:
{
"$": "$.metadata.lastUpdated"
}
or
{
"$": "$.(?[# != 'stringJson'])"
}
but none of these worked for me.
Set InputPath to $.metadata to get:
{
"lastUpdated": "2020-05-27T08:00:00.000Z"
}
Reference paths (the type of path that InputPath accepts) is limited in that it can only identify a single node within the entire JSON structure.
You can't natively exclude all elements except 'x' element.

Elastic search collapse with nested object

I have an elastic search index
like
{
"title": "A",
"comments": [
{
"id": "1"
},
{
"id": "2"
}
]
},
{
"title": "B",
"comments": [
{
"id": "1"
},
{
"id": "3"
}
]
},
{
"title": "C",
"comments": [
{
"id": "7"
},
{
"id": "3"
}
]
}
I want to collapse is the group by the nested object. In the above JSON, I want to group it by Id.
So the output will be like
hits:[{
"title": "A",
"comments": [
{
"id": "1"
},
{
"id": "2"
}
]
},
inner_hits {[
{
"title": "A",
"comments": [
{
"id": "1"
},
{
"id": "2"
}
]
},
{
"title": "B",
"comments": [
{
"id": "1"
},
{
"id": "3"
}
]
}
]}
}]
Baiscally I need collapse bases on the nested object property.
Tried this
/_search?track_total_hits=true
{
"collapse": {
"field": "comments.id",
"inner_hits": {
"name": "id",
"size": 10
},
"max_concurrent_group_searches": 3
}
}
But its always returing first object only in the inner hits
Within the mapping of the object comments , you should remove the nested type.

JsonPath - Extract object meeting multiple criteria?

In the Json string given below, I want to find all elements in which category = m AND the "middle" array contains elements which match this condition - the element's "middle" array has objects whose itemType = Executable.
I would like to use jsonpath to get the desired objects. I prefer to not use jmespath because it can be too complex for my purpose. But, I am new to jsonpath and I am not able to figure out the json query from online tutorials which are too trivial or basic. I wonder if its better to use a programming language instead to get the data I need. Please advise.
So far, I was able to only extract elements in which category = m by using this jsonpath query $.[?(#.category=="m")]. How do I do the remaining part ?
Json :
Overview - Every object has a "content" object. Each content object generally has a start, middle and end array besides other fields. Middle arrays can have multiple content objects inside them and so on. Some of the content objects have only a middle array. I am interested in locating items in such content objects as mentioned above.
Note that this is not the actual json which I have to process. It is an imitation which has been sanitized for SO.
{
"id": "123",
"contents": {
"title": "B1",
"start": [],
"middle": [
{
"level": "1",
"contents": {
"title": "C1",
"category": "c",
"start": [],
"middle": [
{
"level": "2",
"contents": {
"title": "M1",
"category": "m",
"start": [],
"middle": [
{
"level": "3",
"contents": {
"title": "MAT1",
"middle": [
{
"itemType": "Data"
}
]
}
},
{
"level": "3",
"contents": {
"title": "MAT2",
"middle": [
{
"itemType": "Executable",
"id": "exec1"
}
]
}
},
{
"level": "3",
"contents": {
"title": "MAT3",
"middle": [
{
"itemType": "Data"
}
]
}
}
],
"end": []
}
},
{
"level": "2",
"contents": {
"title": "M2",
"category": "m",
"start": [],
"middle": [
{
"level": "3",
"contents": {
"title": "MAT1",
"middle": [
{
"itemType": "Data"
}
]
}
},
{
"level": "3",
"contents": {
"title": "MAT2",
"middle": [
{
"itemType": "Executable",
"id": "exec2"
}
]
}
}
],
"end": []
}
}
],
"end": []
}
},
{
"level": "1",
"contents": {
"title": "C2",
"category": "c",
"start": [],
"middle": [
{
"level": "2",
"contents": {
"title": "M1",
"category": "m",
"start": [],
"middle": [
{
"level": "3",
"contents": {
"title": "MAT1",
"middle": [
{
"itemType": "Data"
}
]
}
},
{
"level": "3",
"contents": {
"title": "MAT2",
"middle": [
{
"itemType": "Executable",
"id": "exec3"
}
]
}
},
{
"level": "3",
"contents": {
"title": "MAT3",
"middle": [
{
"itemType": "Data"
}
]
}
}
],
"end": []
}
},
{
"level": "2",
"contents": {
"title": "M2",
"category": "m",
"start": [],
"middle": [
{
"level": "3",
"contents": {
"title": "MAT1",
"middle": [
{
"itemType": "Data"
}
]
}
},
{
"level": "3",
"contents": {
"title": "MAT2",
"middle": [
{
"itemType": "Executable",
"id": "exec4"
}
]
}
},
{
"level": "3",
"contents": {
"title": "MAT3",
"middle": [
{
"itemType": "Data"
}
]
}
}
],
"end": []
}
}
],
"end": []
}
}
],
"end": []
}
}
Context
json with nested objects1
jsonpath expression language
choosing between jsonpath and jmespath (or other JSON expression engine)
Problem
DeveMasterJoe2 wants to extract some values from nested JSON
Discussion
There are lots of implementations of jsonpath out there, and they do not all support the same features
The structure and normalization of the source JSON is going to influence how easily this can be done with pure jsonpath
In choosing a JSON expression engine, one has to weigh multiple factors
how consistent are the implementations across languages?
how many choices are there within a given language?
how clear is the specification?
how many examples, unit-tests or tutorials are available?
who is supporting it?
Example solution using Python and jsonpath-ng
Here is an example solution using python 3.7 and jsonpath-ng
This example uses a mix of jsonpath and python instead of just pure jsonpath, because of the heavily-nested JSON
I will leave it for someone else to provide an answer that relies on pure jsonpath
Note that the source JSON arguably could stand to be cleaned up a bit
(for example, why is there no id field attached to itemType==Data elements?)
(for example, why is category not found on all contents elements?)
(for example, if you expressly specify level why complicate things with heavily nested objects when you can determine depth by level ?)
This example:
## import libraries
import codecs
import json
import jsonpath_ng
from jsonpath_ng.ext import parse
##;;
## init vars
href="path/to/my/jsonfile/nested_dict.json"
json_string = codecs.open(href, 'rb', encoding='utf8').read()
json_dataroot = json.loads(json_string)
final_result = []
##;;
## init jsonpath outer-query
match = parse('$..contents.middle[*]').find(json_dataroot)
##;;
## iterate through outer-query and gather subelements
for ijj,item in enumerate(match):
## restrict to desired category == 'm'
if(match[ijj].value.get('contents',{}).get('category','') == 'm'):
## extract out desired subelements
json_datafrag001 = [item.get('contents',{}).get('middle',{})[0]
for item in match[ijj].value.get('contents',{}).get('middle',{})
]
match001 = parse("$[?(#.itemType=='Executable')]").find(json_datafrag001)
final_result.extend(list(match001[ikk].value for ikk,item in enumerate(match001)))
pass
##;;
## show final result
vout = json.dumps(final_result, sort_keys=True,indent=4, separators=(',', ': '))
print(vout)
##;;
... produces this result ...
[
{
"id": "exec1",
"itemType": "Executable"
},
{
"id": "exec2",
"itemType": "Executable"
},
{
"id": "exec3",
"itemType": "Executable"
},
{
"id": "exec4",
"itemType": "Executable"
}
]
1 (aka dictionary, associative-array, hash)

denormalizing JSON with jq

I have JSON that looks like this:
[
{
"fields": {
"versions": [
{
"id": "36143",
"name": "ST card"
},
{
"id": "36144",
"description": "Acceptance test card",
"name": "AT card"
}
],
"severity": {
"value": "B-Serious",
"id": "14231"
}
}
},
{
"fields": {
"versions": [
{
"id": "36145",
"name": "ST card"
}
],
"severity": {
"value": "C-Limited",
"id": "14235"
}
}
}
]
I want to convert it with jq to this:
[
{
"id": "36143",
"name": "ST card"
"value": "B-Serious"
},
{
"id": "36144",
"name": "AT card"
"value": "B-Serious"
},
{
"id": "36145",
"name": "ST card"
"value": "C-Limited"
}
]
Note that the first object has 2 versions, and the same severity. I have tried jq's group_by and map functions but haven't been too successful. Please help :)
This should work. You wouldn't want to use a group_by here, you would do that if you were trying to go from more to less, we're going the other way.
You're combining the different versions with the corresponding severity. Here's how you could do that.
map(.fields | (.versions[] | { id, name }) + { value: .severity.value })