unable to add value on nested property - json

I am struggling to modify the data of properties that are deeply nested in my PSObject. If I try to modify the values Powershell just throws the exception of saying that it cannot find the value, but if I just call upon the value itself it can be found without an issue.
The raw data of the json object looks like this:
[
{
"#CREATED": "2017-05-04 08:36:23",
"#LAST_MODIFIED": "2017-05-08 08:18:58",
"STANDARD_FIELDS": {
"FIRST_NAME": {
"#FIELD_ID": 2,
"#LAST_MODIFIED": "2017-05-04 08:36:24",
"#VALID_FROM": "2017-05-04",
"value": "Example"
},
"LAST_NAME": {
"#FIELD_ID": 3,
"#LAST_MODIFIED": "2017-05-04 08:36:24",
"#VALID_FROM": "2017-05-04",
"value": "User"
},
"ORGANIZATION": {
"#FIELD_ID": 8,
"#MODE": 0,
"#LAST_MODIFIED": "2017-05-04 08:36:24",
"#VALID_FROM": "2017-05-04",
"value": "Example Org"
},
"NAME": {
"#FIELD_ID": 1,
"#MODE": 1,
"#LAST_MODIFIED": "2017-05-04 08:36:24",
"#VALID_FROM": "2017-05-04",
"#ID": 240
},
"SUPERVISOR": {
"#FIELD_ID": 9,
"#MODE": 4,
"#LAST_MODIFIED": "2017-05-04 15:39:30",
"#VALID_FROM": "2017-05-04",
"NAME": "Example User2",
"SYSTEM_ID": "198"
},
"JOB_LOCATION": {
"#FIELD_ID": 14,
"#MODE": 0,
"#LAST_MODIFIED": "2017-05-04 14:26:55",
"#VALID_FROM": "2017-05-04",
"value": "Stockholm"
}
},
"CUSTOM_FIELDS": {
"FIELD": [
{
"#FIELD_ID": 1033,
"#MODE": 0,
"#LAST_MODIFIED": "2017-05-24 10:15:24",
"#VALID_FROM": "2017-05-24",
"NAME": "Department",
"VALUE": {
"value": "Example Department"
}
},
{
"#FIELD_ID": 1034,
"#MODE": 0,
"#LAST_MODIFIED": "2017-05-04 08:36:24",
"#VALID_FROM": "2017-05-04",
"NAME": "VPN",
"VALUE": {
"value": "Yes"
}
},
{
"#FIELD_ID": 1036,
"#LAST_MODIFIED": "2017-05-04 08:36:24",
"#VALID_FROM": "2017-05-04",
"NAME": "Titel",
"VALUE": {
"value": "Test-User"
}
},
{
"#FIELD_ID": 1022,
"#MODE": 0,
"#LAST_MODIFIED": "2017-05-04 16:43:18",
"#VALID_FROM": "2017-05-04",
"NAME": "Authorizations",
"VALUES": {
"VALUE": [
{
"value": "Auth 1"
},
{
"value": "Auth 2"
},
{
"value": "Auth 3"
},
{
"value": "Auth 4"
}
]
}
}
]
}
}
]
My current code:
$users = get-content "C:\Working-Branch\Temp\NotFoundUsers - Copy.txt"| ConvertFrom-Json
foreach($user in $users){
$user.CUSTOM_FIELDS.FIELD.values.Value.value
$NewValue = $user.CUSTOM_FIELDS.FIELD.values.Value.value
$NewValue += "Test"
$NewValue
$($user.CUSTOM_FIELDS.FIELD.values.Value).value = $newValue
}
Which results in the following output:
Auth 1
Auth 2
Auth 3
Auth 4
Auth 1
Auth 2
Auth 3
Auth 4
Test
The property 'value' cannot be found on this object. Verify that the property exists and can be set.
At line:10 char:5
+ $($user.CUSTOM_FIELDS.FIELD.values.Value).value = $newValue
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : PropertyAssignmentException
So I know the property exists because I call upon it two times, one directly on the Object and one time after I have added the value "test" to it. But when I try to update the Orignal object it says it can not find the value "Value" on the object.
I tried following the what was suggested in This post, but it still fails for me. I both with the "+=" operator and the "=" operator. Same error with both of them.
Result of Get-member

I think you need to find the field with the member Values
$newvalue =#{
"value" = "Test"
}
foreach($user in $users){
$array = $user.CUSTOM_FIELDS.FIELD.values.value
$array += $newvalue
foreach ($field in $user.CUSTOM_FIELDS.FIELD)
{
if ($field.values -ne $null)
{
$field.values.value = $array
}
}
$user.CUSTOM_FIELDS.FIELD.values.Value
}
Then output for $user.CUSTOM_FIELDS.FIELD.values.Value is
value
-----
Auth 1
Auth 2
Auth 3
Auth 4
Test

Related

Postman accessing child objects in Json in a Test

I am trying to access the name object in this Json to put in a local variable in a Postman Test.
Json
{
"Line": [
{
"Id": "1",
"LineNum": 1,
"Description": "Custom Design",
"Amount": 75.00,
"DetailType": "SalesItemLineDetail",
"SalesItemLineDetail": {
"ItemRef": {
"value": "4",
"name": "Design"
},
"UnitPrice": 75,
"Qty": 1,
"ItemAccountRef": {
"value": "82",
"name": "Design income"
},
"TaxCodeRef": {
"value": "NON"
}
}
}
]
}
I am using this code to loop through the Line Array but if I try and go deeper than 1 level Itemref it returns undefined
let ProductArray=[];
for (let i=0; i < Line.length; i++) {
//
ProductArray.push({
"value":Line[i].SalesItemLineDetail.ItemRef.name
})
}
I have also tried
'"value":Line[i].SalesItemLineDetail["ItemRef"].name
"value":Line[i].SalesItemLineDetail["ItemRef"]["name"]
all return ItemRef undefined
What is the correct syntax or code?
TIA
There are just some small pieces missing with your code. I re-create a test and mocked the same JSON data. I just add the missing pieces to your code and the test was Successful.
GET Request:
//Response body JSON
{
"Line": [
{
"Id": "1",
"LineNum": 1,
"Description": "Custom Design",
"Amount": 75,
"DetailType": "SalesItemLineDetail",
"SalesItemLineDetail": {
"ItemRef": {
"value": "4",
"name": "Design"
},
"UnitPrice": 75,
"Qty": 1,
"ItemAccountRef": {
"value": "82",
"name": "Design income"
},
"TaxCodeRef": {
"value": "NON"
}
}
}
]
}
// Tests
// Check response body
const res = pm.response.json().Line;
let ProductArray=[];
for (let i=0; i < res.length; i++) {
const res = pm.response.json().Line;
ProductArray.push({
"value":res[i].SalesItemLineDetail.ItemRef.name
})
// Lets see console.log result
console.log('Check For:', res[i].SalesItemLineDetail.ItemRef.name)
// Set Result to environment variables
pm.environment.set("variable_key", res[i].SalesItemLineDetail.ItemRef.name);
}
console.log output: Design which is also added to environment variables.

How to store and retrieve nested JSON array in laravel 6

I am trying to retrieve the data saved as json in mysql. My migration looks like below:
Schema::create('items', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name')->nullable();
$table->json('add_ons')->nullable();
$table->timestamps();
});
I have tried saving the below JSON from postman and it saved perfectly.
{
"itemName": "chicken",
"addons": {
"required": false,
"min": 2,
"max": 3,
"data": [
{
"name": "sauces",
"type": [
{
"name": "white sauce",
"type": [
{
"name": "whiteOne",
"price": 10
},
{
"name": "whiteTwo",
"price": 20
}
]
},
{
"name": "red sauce",
"price": 10
}
]
}
]
}
}
Now, I trying to retrieve the price of 'whiteOne' under 'white sauce' and getting nothing other than null or laravel error response.
I have tried
Item::whereJsonContains('add_ons->data->name','sauces')->get()
Item::whereJsonContains('add_ons->data->name','sauces')->find(16)
After saving the 'add_ons' column has below data:
{
"required": false,
"min": 2,
"max": 3,
"data": [
{
"name": "sauces",
"type": [
{
"name": "white sauce",
"type": [
{
"name": "whiteOne",
"price": 10
},
{
"name": "whiteTwo",
"price": 20
}
]
},
{
"name": "red sauce",
"price": 10
}
]
}
]
}
Can anyone help me ?
I used this function to get the value of the index.
public function search($array, $key, $value) {
// RecursiveArrayIterator to traverse an
// unknown amount of sub arrays within
// the outer array.
$arrIt = new \RecursiveArrayIterator($array);
// RecursiveIteratorIterator used to iterate
// through recursive iterators
$it = new \RecursiveIteratorIterator($arrIt);
foreach ($it as $sub) {
// Current active sub iterator
$subArray = $it->getSubIterator();
if ($subArray[$key] === $value) {
//$result[] = iterator_to_array($subArray);
$result = iterator_to_array($subArray);
}
}
return $result;
}
Now when I pass the values in the function I get the appropriate values.
$item = Item::where('id','=',16)->first();
$res = $this->search($item->add_ons['data'], 'name', 'whiteTwo');
echo $res["name"]." - ".$res['price'] ."<br>";

How do i validate a dynamic JSON key?

{
"id": "aghysfgagaw365",
"MetricLevelId": "4890718305",
"level": "BUB",
"type": "Mash",
"summary": {
"counts": [
{},
{
"label": {},
"value": 2674,
"labelLoc": {
"192706": {
"ADD": 8977,
"DEL": 3257,
"Count": 59
},
"543419": {
"ADD": 0,
"DEL": 0,
"Count": 1
}
}
}
]
}
}
I read the documentation but i'm still unclear to validate a complex API's like this. a demo to validate this API would help me to solve other API validations...especially this one has a dynamic JSON key.how do i validate ADD,DEL and Cont with "192706" being dynamic.
From the docs, please refer to the documentation on JsonPath. Also recommended is the section on "JSON Transforms". Here is one way:
* def response =
"""
{
"id": "aghysfgagaw365",
"MetricLevelId": "4890718305",
"level": "BUB",
"type": "Mash",
"summary": {
"counts": [
{
},
{
"value": 2674,
"labelLoc": {
"192706": {
"ADD": 8977,
"DEL": 3257,
"Count": 59
},
"543419": {
"ADD": 0,
"DEL": 0,
"Count": 1
}
}
}
]
}
}
"""
* def label = get[0] response..labelLoc
* def vals = get label.*
* match each vals == { ADD: '#number', DEL: '#number', Count: '#number' }
EDIT also this would work:
* json keys = label.keySet()
* match keys == ['192706', '543419']

How to access Dynamodb's original JSON elements?

I am trying to test my lambda manually with the following dynamodb event input configured in tests -
Let's call this Json-1
{
"Records": [
{
"eventID": "1",
"eventVersion": "1.0",
"dynamodb": {
"Keys": {
"Id": {
"N": "101"
}
},
"NewImage": {
"Message": {
"S": "New item!"
},
"Id": {
"N": "101"
}
},
"StreamViewType": "NEW_AND_OLD_IMAGES",
"SequenceNumber": "111",
"SizeBytes": 26
},
"awsRegion": "us-west-2",
"eventName": "INSERT",
"eventSourceARN": eventsourcearn,
"eventSource": "aws:dynamodb"
},
{
"eventID": "2",
"eventVersion": "1.0",
"dynamodb": {
"OldImage": {
"Message": {
"S": "New item!"
},
"Id": {
"N": "101"
}
},
"SequenceNumber": "222",
"Keys": {
"Id": {
"N": "101"
}
},
"SizeBytes": 59,
"NewImage": {
"Message": {
"S": "This item has changed"
},
"Id": {
"N": "101"
}
},
"StreamViewType": "NEW_AND_OLD_IMAGES"
},
"awsRegion": "us-west-2",
"eventName": "MODIFY",
"eventSourceARN": sourcearn,
"eventSource": "aws:dynamodb"
},
{
"eventID": "3",
"eventVersion": "1.0",
"dynamodb": {
"Keys": {
"Id": {
"N": "101"
}
},
"SizeBytes": 38,
"SequenceNumber": "333",
"OldImage": {
"Message": {
"S": "This item has changed"
},
"Id": {
"N": "101"
}
},
"StreamViewType": "NEW_AND_OLD_IMAGES"
},
"awsRegion": "us-west-2",
"eventName": "REMOVE",
"eventSourceARN": sourcearn,
"eventSource": "aws:dynamodb"
}
]
}
However, the json of dynamodb items look like this -
Let's call this Json-2
{
"id": {
"S": "RIGHT-aa465568-f4c8-4822-9c38-7563ae0cd37b-1131286033464633.jpg"
},
"lines": {
"L": [
{
"M": {
"points": {
"L": [
{
"L": [
{
"N": "0"
},
{
"N": "874.5625"
}
]
},
{
"L": [
{
"N": "1765.320601851852"
},
{
"N": "809.7800925925926"
}
]
},
{
"L": [
{
"N": "3264"
},
{
"N": "740.3703703703704"
}
]
}
]
},
"type": {
"S": "guard"
}
}
}
]
},
"modified": {
"N": "1483483932472"
},
"qastatus": {
"S": "reviewed"
}
}
Using the lambda function below, I can connect to my table. My goal is create a json which elastic search will accept.
#Override
public Object handleRequest(DynamodbEvent dynamodbEvent, Context context) {
List<DynamodbEvent.DynamodbStreamRecord> dynamodbStreamRecordlist = dynamodbEvent.getRecords();
DynamoDB dynamoDB = new DynamoDB(new AmazonDynamoDBClient());
log.info("Whole event - "+dynamodbEvent.toString());
dynamodbStreamRecordlist.stream().forEach(dynamodbStreamRecord -> {
if(dynamodbStreamRecord.getEventSource().equalsIgnoreCase("aws:dynamodb")){
log.info("one record - "+dynamodbStreamRecord.getDynamodb().toString());
log.info(" getting N from new image "+dynamodbStreamRecord.getDynamodb().getNewImage().toString());
String tableName = getTableNameFromARN(dynamodbStreamRecord.getEventSourceARN());
log.info("Table name :"+tableName);
Map<String, AttributeValue> keys = dynamodbStreamRecord.getDynamodb().getKeys();
log.info(keys.toString());
AttributeValue attributeValue = keys.get("Id");
log.info("Value of N: "+attributeValue.getN());
Table table = dynamoDB.getTable(tableName);
}
});
return dynamodbEvent;
}
The format of a JSON item that elastic search expects is this and this is what I want to map the test input json to-
Let's call this Json-3
{
_index: "bar-guard",
_type: "bar-guard_type",
_id: "LEFT-b1939610-442f-4d8d-9991-3ca54685b206-1147042497459511.jpg",
_score: 1,
_source: {
#SequenceNumber: "4901800000000019495704485",
#timestamp: "2017-01-04T02:24:20.560358",
lines: [{
points: [[0,
1222.7129629629628],
[2242.8252314814818,
1254.702546296296],
[4000.0000000000005,
1276.028935185185]],
type: "barr"
}],
modified: 1483483934697,
qastatus: "reviewed",
id: "LEFT-b1939610-442f-4d8d-9991-3ca54685b206-1147042497459511.jpg"
}
},
So what I need is read Json-1 and map it to Json-3.
However, Json-1 does not seem to be complete i.e. it does not have information that a dynamodb json has - like points and lines in Json-2.
And so, I was trying to get a connection to the original table and then read this additional information of lines and points by using the ID.
I am not sure if this is the right approach. Basically, want to figure out a way to get the actual JSON that dynamodb has and not the one that has attribute types
How can I get lines and points from json-2 using java? I know we have DocumentClient in javascript but I am looking for something in java.
Also, came across a converter here but doesn't help me- https://github.com/aws/aws-sdk-js/blob/master/lib/dynamodb/converter.js
Is this something that I should use DynamoDBMapper or ScanJavaDocumentAPI for ?
http://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/dynamodbv2/datamodeling/DynamoDBMapper.html#marshallIntoObjects-java.lang.Class-java.util.List-com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperConfig-
If yes, I am a little lost how to do that in the code below -
ScanRequest scanRequest = new ScanRequest().withTableName(tableName);
ScanResult result = dynamoDBClient.scan(scanRequest);
for(Map<String, AttributeValue> item : result.getItems()){
AttributeValue value = item.get("lines");
if(value != null){
List<AttributeValue> values = value.getL();
for(AttributeValue value2 : values){
//what next?
}
}
}
Ok, this seems to work for me.
ScanRequest scanRequest = new ScanRequest().withTableName(tableName);
ScanResult result = dynamoDBClient.scan(scanRequest);
for(Map<String, AttributeValue> item : result.getItems()){
AttributeValue value = item.get("lines");
if(value != null){
List<AttributeValue> values = value.getL();
for(AttributeValue value2 : values){
if(value2.getM() != null)
{
Map<String, AttributeValue> map = value2.getM();
AttributeValue points = map.get("points");
List<AttributeValue> pointsvalues = points.getL();
if(!pointsvalues.isEmpty()){
for(AttributeValue valueOfPoint : pointsvalues){
List<AttributeValue> pointList = valueOfPoint.getL();
for(AttributeValue valueOfPoint2 : pointList){
}
}
}
}
}
}
}

MongoDB - How to $inc in a double nested array

I'm trying to increment c every time a user choose a label.
My sample dataset has two nested arrays:
{
"id": 123,
"labels": [
{
"label": "orange",
"hitCount": 2,
"hits": [
{
"who": "bob",
"c": "2"
}
]
},
{
"label": "red",
"hitCount": 6,
"hits": [
{
"who": "bob",
"c": "5"
},
{
"who": "alice",
"c": "1"
}
]
}
]
}
For example bob choose again red so I want to increment the c inside bob's object inside red's object from 5 to 6.
I can't use $ two times to navigate inside more than one array per https://docs.mongodb.com/manual/reference/operator/update/positional/#nested-arrays
So anyone knows how to traverse more than one level of array and obtain a reference for $inc?
I suggest you to change you data model to:
{
"id": 123,
"labels": [
{
"label": "orange",
"hitCount": 2,
"hits": {
"bob": 2
}
},
{
"label": "red",
"hitCount": 6,
"hits": {
"bob":5,
"alice":1
}
}
]
}
Then you could update hits using this command:
db.hits.update(
{ 'labels.label': 'red' },
{ '$inc': { 'labels.$.hitCount': 1, 'labels.$.hits.bob': 1 } }
);
If you need to construct update with dynamic username, you can do it:
var userName = 'bob';
var updateCommand = {
$inc: {
'labels.$.hitCount': 1
}
};
updateCommand.$inc['labels.$.hits.' + userName] = 1;
db.hits.update({ 'labels.label': 'red' }, updateCommand);