Json Path property filter structure - json.net

newtonsoft version 13.0.1
given the object data which is a JToken with the content of:
{
"myString": "demo2",
"myNumber": 2.2,
"myInteger": 20,
"myObject": {
"myObject": {
"myArray": [
2,
20,
200,
2000
]
},
"myArray": [
2,
20,
200,
2000
]
},
"myArray": [
2,
20,
200,
2000
],
"myBoolean": true,
"myNull": null
}
and the selecttokens command like this.
data.SelectTokens("$..myObject[?(#.myArray)]")
I expect to get one object back. but it doesn't return any. Is there something I do wrong here?
if I try it on https://jsonpath.com/ it will return me an object.
or should I test it like $..[?(#.myObject.myArray)]

Related

How to remove "Double braces {{}}" in a property of dynamic type during deserialization (ASp.Net Core MVC)

When deserializing a string, the curly braces are duplicating and this is disturbing the reading of some fields. I've tried everything, but I can't serialize correctly, without duplicate curly braces.
I already tried to do it like this:
dynamic values = JsonConvert.DeserializeObject<dynamic>(storedEvent.Data);
The storedEvent.Data property is of type string and contains this information:
"{\"PaisId\":31,\"PaisDivisaoAdministrativaNivelRemovedEventList\":[{\"Id\":6,\"PaisId\":31,\"PaisNomePtBr\":\"\",\"PaisDivisaoAdministrativaTipoId\":5,\"PaisDivisaoAdministrativaTipoNome\":\"Município\",\"PaisDivisaoAdministrativaTipoOrigemId\":5,\"Timestamp\":\"2022-11-24T20:16:15.6020289-03:00\",\"MessageType\":\"PaisDivisaoAdministrativaNivelRemovedEvent\",\"AggregateId\":6},{\"Id\":5,\"PaisId\":31,\"PaisNomePtBr\":\"\",\"PaisDivisaoAdministrativaTipoId\":1,\"PaisDivisaoAdministrativaTipoNome\":\"Estado\",\"PaisDivisaoAdministrativaTipoOrigemId\":null,\"Timestamp\":\"2022-11-24T20:16:15.6580242-03:00\",\"MessageType\":\"PaisDivisaoAdministrativaNivelRemovedEvent\",\"AggregateId\":5}],\"Timestamp\":\"2022-11-24T20:16:16.1892039-03:00\",\"MessageType\":\"PaisDivisaoAdministrativaNivelHierarquiasRemovedEvent\",\"AggregateId\":31}"
Result obtained (Duplicate curly braces):
{{
"PaisId": 31,
"PaisDivisaoAdministrativaNivelRemovedEventList": [
{
"Id": 6,
"PaisId": 31,
"PaisNomePtBr": "",
"PaisDivisaoAdministrativaTipoId": 5,
"PaisDivisaoAdministrativaTipoNome": "Município",
"PaisDivisaoAdministrativaTipoOrigemId": 5,
"Timestamp": "2022-11-24T20:16:15.6020289-03:00",
"MessageType": "PaisDivisaoAdministrativaNivelRemovedEvent",
"AggregateId": 6
},
{
"Id": 5,
"PaisId": 31,
"PaisNomePtBr": "",
"PaisDivisaoAdministrativaTipoId": 1,
"PaisDivisaoAdministrativaTipoNome": "Estado",
"PaisDivisaoAdministrativaTipoOrigemId": null,
"Timestamp": "2022-11-24T20:16:15.6580242-03:00",
"MessageType": "PaisDivisaoAdministrativaNivelRemovedEvent",
"AggregateId": 5
}
],
"Timestamp": "2022-11-24T20:16:16.1892039-03:00",
"MessageType": "PaisDivisaoAdministrativaNivelHierarquiasRemovedEvent",
"AggregateId": 31
}}
Expected:
{
"PaisId": 31,
"PaisDivisaoAdministrativaNivelRemovedEventList": [
{
"Id": 6,
"PaisId": 31,
"PaisNomePtBr": "",
"PaisDivisaoAdministrativaTipoId": 5,
"PaisDivisaoAdministrativaTipoNome": "Município",
"PaisDivisaoAdministrativaTipoOrigemId": 5,
"Timestamp": "2022-11-24T20:16:15.6020289-03:00",
"MessageType": "PaisDivisaoAdministrativaNivelRemovedEvent",
"AggregateId": 6
},
{
"Id": 5,
"PaisId": 31,
"PaisNomePtBr": "",
"PaisDivisaoAdministrativaTipoId": 1,
"PaisDivisaoAdministrativaTipoNome": "Estado",
"PaisDivisaoAdministrativaTipoOrigemId": null,
"Timestamp": "2022-11-24T20:16:15.6580242-03:00",
"MessageType": "PaisDivisaoAdministrativaNivelRemovedEvent",
"AggregateId": 5
}
],
"Timestamp": "2022-11-24T20:16:16.1892039-03:00",
"MessageType": "PaisDivisaoAdministrativaNivelHierarquiasRemovedEvent",
"AggregateId": 31
}
Does anyone know of a solution?
Using dynamic is not a good option to work with Json objects dynamically
For this, you can use Jobject as follows
using Newtonsoft.Json.Linq;
string jsonStr= "{\"PaisId\":31,\"PaisDivisaoAdministrativaNivelRemovedEventList\":[{\"Id\":6,\"PaisId\":31,\"PaisNomePtBr\":\"\",\"PaisDivisaoAdministrativaTipoId\":5,\"PaisDivisaoAdministrativaTipoNome\":\"Município\",\"PaisDivisaoAdministrativaTipoOrigemId\":5,\"Timestamp\":\"2022-11-24T20:16:15.6020289-03:00\",\"MessageType\":\"PaisDivisaoAdministrativaNivelRemovedEvent\",\"AggregateId\":6},{\"Id\":5,\"PaisId\":31,\"PaisNomePtBr\":\"\",\"PaisDivisaoAdministrativaTipoId\":1,\"PaisDivisaoAdministrativaTipoNome\":\"Estado\",\"PaisDivisaoAdministrativaTipoOrigemId\":null,\"Timestamp\":\"2022-11-24T20:16:15.6580242-03:00\",\"MessageType\":\"PaisDivisaoAdministrativaNivelRemovedEvent\",\"AggregateId\":5}],\"Timestamp\":\"2022-11-24T20:16:16.1892039-03:00\",\"MessageType\":\"PaisDivisaoAdministrativaNivelHierarquiasRemovedEvent\",\"AggregateId\":31}";
var obj = JObject.Parse(jsonStr);
//access properties
var paisId = obj["PaisId"];
//Access to PaisDivisaoAdministrativaNivelRemovedEventList
var paisList = obj["PaisDivisaoAdministrativaNivelRemovedEventList"].ToList();
//search on PaisDivisaoAdministrativaNivelRemovedEventList
var result = paisList.FirstOrDefault(x => (int)x["Id"] == 6);
You have to fix the code that returns the double braces string. If you don't have access to this code, the only way to get rid of double braces is to use string function
storedEvent.Data=storedEvent.Data.Substring(1,Data.Length-2);
after this you can use your code if you like, but I don't like dynamic, IMHO it is better to use Parse and sqware brakets to get data.

Using mongolite in R to extract individual array items

I'm using mongolite in R to read a mongo collection with the following structure:
[{_id: 0, date: 20221201, dailyAnswer:[
{question:a,score:1},
{question:b,score:3},
{question:c,score:2}
]},
{_id: 1, date: 20221201, dailyAnswer:[
{question:a,score:3},
{question:b,score:2},
{question:c,score:1}
]},
{_id: 0, date: 20221202, dailyAnswer:[
{question:a,score:2},
{question:b,score:2},
{question:c,score:3}
]},
{_id: 1, date: 20221202, dailyAnswer:[
{question:a,score:3},
{question:b,score:1},
{question:c,score:1}
]}]
For each document I'd like to extract each question score into a column, with the table structure:
_id | date | question_a_score | question_b_score | question_c_score
In MongoDB Compass I've written a query to extract them:
{
q_a_score: { $arrayElemAt: [ "$dailyAnswer.score",0]},
q_b_score: { $arrayElemAt: [ "$dailyAnswer.score",1]},
q_c_score: { $arrayElemAt: [ "$dailyAnswer.score",2]}
}
Which returns:
[{
_id: 0,
question_a_score:1,
question_b_score:3,
question_c_score:2},
...,
{
_id: 1,
question_a_score:3,
question_b_score:1,
question_c_score:1}
}]
However, I'm not sure whether to use the $aggregate or $find methods in mongolite in R, and how to structure the pipeline or query arguments in those methods respectively.
Use the aggregate method with the $project and $arrayElemAt operators:
checkins_questions <- collection_connection$aggregate(pipeline = '[{"$project": {"dailyAnswerScore1": { "$arrayElemAt": [ "$dailyAnswer.score", 0 ] },
"dailyAnswerScore2": { "$arrayElemAt": [ "$dailyAnswer.score", 1 ] },
"dailyAnswerScore3": { "$arrayElemAt": [ "$dailyAnswer.score", 2 ] }}}]')

R - JSON Structure for POST

I've read everything i can find around create JSONs using toJSON(), but it's just not clicking. Any guidance would be greatly appreciated.
I am trying to create a JSON for a POST request to an API. I'm trying to create the following structure:
{
"configuration": {
"Id": 1,
"OptionIds": [
261,
263,
533122,
228
]
},
"length": 15000,
"zip": "92691",
"Date": "2019-09-11T15:46:31.354Z"
}
Trying to break it down element by element I can begin to get close, but can never get to the final solution once attempt to combine everything.
For example.
v_opt_ids <- list(OptionsIds = c(261,
263,
533122,
228))
cat(jsonlite::toJSON(v_opt_ids, pretty=T))
Produces:
{
"OptionsIds": [261, 263, 533122, 228]
}
And while this is not exactly what i'm aiming for in that portion, when combined with additional elements.
config <- data.frame(
vehicleId = c(444449),
v_opt_ids)
cat(jsonlite::toJSON(list(configuration = config), pretty=T))
Things go awry pretty quickly..
{
"configuration": [
{
"vehicleId": 444449,
"OptionsIds": 261
},
{
"vehicleId": 444449,
"OptionsIds": 263
},
{
"vehicleId": 444449,
"OptionsIds": 533122
},
{
"vehicleId": 444449,
"OptionsIds": 228
}
]
}
Any guidance would be greatly appreciated.
Use nested lists:
L <- list(
configuration = list(
Id = 1,
OptionIds = c(261, 263, 533122, 228)
),
length = 15000,
zip = "92691",
Date = "2019-09-11T15:46:31.354Z"
)
jsonlite::toJSON(L, pretty = TRUE, auto_unbox = TRUE)
# {
# "configuration": {
# "Id": 1,
# "OptionIds": [261, 263, 533122, 228]
# },
# "length": 15000,
# "zip": "92691",
# "Date": "2019-09-11T15:46:31.354Z"
# }
(pretty=TRUE is not required for the JSON, just using it to attempt to match your expected output. auto_unbox=TRUE ensures that one gets "Id":1 instead of "Id":[1], which is functionally identical for most things that consume json, some find it a preferable format.

Problem setting edges in vis-network with typescript

I'm following the Dynamic Dataset example from vis and I'm getting a typescript error when I try to set edges.
I just have an edge array that looks like:
edgesArray = [
{ from: 1, to: 3 },
{ from: 1, to: 2 },
{ from: 2, to: 4 },
{ from: 3, to: 5 },
]
and I'm setting the data as
let data = {
nodes: new vis.DataSet(nodesArray),
edges: new vis.DataSet(edgesArray)
}
The error I'm getting is in the edges.
No overload matches this call.
Overload 1 of 2, '(options?: DataSetInitialOptions<"id">): DataSet<Partial<Record<"id", string | number>>, "id">', gave the following error.
Type '{ from: number; to: number; } []' has no properties in common with type 'DataSetInitialOptions<"id">'.
Overload 2 of 2, '(data: Partial<Record<"id", string | number>>[], options?: DataSetInitialOptions<"id">): DataSet<Partial<Record<"id", string | number>>, "id">', gave the following error.
Argument of type '{ from: number; to: number; } []' is not assignable to parameter of type 'Partial<Record<"id", string | number>>[]'.
I'm using version 5.2.4 of vis-network.
This is standard TS behavior. You're trying to assign type A into B but they have nothing in common. DataSet can accept items that have optional id. However your edges have no ids and TS simply says you're doing something wrong.
Solution one:
import { Edge } from "vis-network";
const edgesArray: Edge[] = [
{ from: 1, to: 3 },
{ from: 1, to: 2 },
{ from: 2, to: 4 },
{ from: 3, to: 5 },
];
Solution two:
const edgesArray = [
{ id: undefined, from: 1, to: 3 },
{ from: 1, to: 2 },
{ from: 2, to: 4 },
{ from: 3, to: 5 },
];
Solution three:
const edgesArray: { id?: undefined, from: number, to: number }[] = [
{ from: 1, to: 3 },
{ from: 1, to: 2 },
{ from: 2, to: 4 },
{ from: 3, to: 5 },
];

Using a key within a map

I have this function:
def getMap(value = null) {
[
"SomeTitle": [ Param: 9, Size: 2, Default: 150, Val: value ]
]
}
and I can use getMap(152).SomeTitle.Val
What I want to do is use the key Size while calculating the Key Val, something like:
def getMap(value = null) {
[
"SomeTitle": [ Param: 9, Size: 2, Default: 150, Val: value * Size ]
]
}
Is there a way to use the Value of a Key within a map as a variable while calculating the Value of a another Key
This in Java/Groovy
Groovy can't autoreference the map on it's initialization, but you can use a with {} method to do some post-initialization processing:
def getMap(value = null) {
[
"SomeTitle": [ Param: 9, Size: 2, Default: 150 ].with {
put('Val', value * get('Size'))
it
}
]
}
assert getMap(10).SomeTitle.Val == 20

Resources