Select first N elements from JSon - jsonpath

{"id1":"value1", "id2":"value2", "id3":"value3", "id4":"value4", "id5":"value5" ... etc.
$.* returns:
"value1",
"value2",
"value3",
"value4" ... etc
There are thousands values there. But I need only some specific number.
Is there a way to select them?
I need something like $.[0:N]
but proper one.

Related

r json mongodb query $in operator syntax error due to double quotes?

I'm building a json query to pass to a mongodb database in R.
In one scenario, I have a vector of dates and I want to query the database to return all records which have a date in the relevant field that matches a date in my vector of dates.
The second scenario is the same as the first, but this time I have a vector of character strings (IDs) and need to return all the records with matching IDs.
I understood the correct way to do this in a json query is to use the $in operator, and then put my vector in an array.
However, when I pass the query to my mongodb database, the exportLogId returns NULL. I'm quite sure that the problem is something to do with how I am representing the $in operator in the final query, since I have very similarly structured queries without the $in operator and they are all working. If I look for just one of my target dates or character strings, I get the desired result.
I followed the mongodb manual here to construct my query, and the only issue I can see is that the $in operator in the output of jsonlite::toJSON() is enclosed in double quotes; whereas I think it might need to be in single quotes (or no quotes at all, but I don't know how to write the syntax for that).
I'm creating my query in two steps:
Create the query as a series of nested lists
Convert the list object to json with jsonlite::toJSON()
Here is my code:
# Load libraries:
library(jsonlite)
# Create list of example dates to query in mongodb format:
sampledates <- c("2022-08-11T00:00:00.000Z",
"2022-08-15T00:00:00.000Z",
"2022-08-16T00:00:00.000Z",
"2022-08-17T00:00:00.000Z",
"2022-08-19T00:00:00.000Z")
# Create query as a list object:
query_list_l <- list(filter =
# Add where clause:
list(where =
# Filter results by list of sample dates:
list(dateSampleTaken = list('$in' = sampledates),
# Define format of column names and values:
useDbColumns = "true",
dontTranslateValues = "true",
jsonReplaceUndefinedWithNull = "true"),
# Define columns to return:
fields = c("id",
"updatedAt",
"person.visualId",
"labName",
"sampleIdentifier",
"dateSampleTaken",
"sequence.hasSequence")))
# Convert list object to JSON:
query_json = jsonlite::toJSON(x = query_list_l,
pretty = TRUE,
auto_unbox = TRUE)
The JSON query now looks like this:
> query_json
{
"filter": {
"where": {
"dateSampleTaken": {
"$in": ["2022-08-11T00:00:00.000Z", "2022-08-15T00:00:00.000Z", "2022-08-16T00:00:00.000Z", "2022-08-17T00:00:00.000Z", "2022-08-19T00:00:00.000Z"]
},
"useDbColumns": "true",
"dontTranslateValues": "true",
"jsonReplaceUndefinedWithNull": "true"
},
"fields": ["id", "updatedAt", "person.visualId", "labName", "sampleIdentifier", "dateSampleTaken", "sequence.hasSequence"]
}
}
As you can see, $in is now enclosed in double quotes, even though I put it in single quotes when I created the query as a list object. I have tried replacing with sprintf() but that just adds a lot of backslashes to my query. I also tried:
query_fixed <- gsub(pattern = "\\"\\$\\in\\"",
replacement = "\\'$in\\'",
x = query_json)
... but this fails with an error.
I would be very grateful to know if:
The syntax problem that is preventing $in from working is actually the double quotes?
If double quotes is the problem, how do I replace them with single quotes without messing up the JSON format?
UPDATE:
The issue seems to occur when R is passing the query to the database, but I still can't work out exactly why.
If I try the query out in loopback explorer in the database, it works and using the export log ID produced, I can then fetch the results with httr::GET() in R. Example query results are shown below (sorry for the hashes - the main point is you can see the format of the returned values):
[1] "[{\"_id\":\"e59953b6-a106-4b69-9e25-1c54eef5264a\",\"updatedAt\":\"2022-09-12T20:08:39.554Z\",\"dateSampleTaken\":\"2022-08-16T00:00:00.000Z\",\"labName\":\"LNG_REFERENCE_DATA_CATEGORY_LAB_NAME_LAB_A\",\"sampleIdentifier\":\"LS0044-SCV2-PCR\",\"sequence\":{\"hasSequence\":false},\"person\":{\"visualId\":\"C-2022-0002\"}},{\"_id\":\"af5cd9cc-4813-4194-b60b-7d130bae47bc\",\"updatedAt\":\"2022-09-12T20:11:07.467Z\",\"dateSampleTaken\":\"2022-08-17T00:00:00.000Z\",\"labName\":\"LNG_REFERENCE_DATA_CATEGORY_LAB_NAME_LAB_A\",\"sampleIdentifier\":\"LS0061-SCV2-PCR\",\"sequence\":{\"hasSequence\":false},\"person\":{\"visualId\":\"C-2022-0003\"}},{\"_id\":\"b5930079-8d57-43a8-85c0-c95f7e0338d9\",\"updatedAt\":\"2022-09-12T20:13:54.378Z\",\"dateSampleTaken\":\"2022-08-16T00:00:00.000Z\",\"labName\":\"LNG_REFERENCE_DATA_CATEGORY_LAB_NAME_LAB_A\",\"sampleIdentifier\":\"LS0043-SCV2-PCR\",\"sequence\":{\"hasSequence\":false},\"person\":{\"visualId\":\"C-2022-0004\"}}]"

How to filter on dictionary with multiples keys

I have a dictionnary with double key which look like this:
{('Year', 'prix'): 130546.87449454193,
('Year', 'departement'): 11591.47409694357,
('Year', 'annee'): 34.28496633835407,
('Year', 'kilometrage'): 414330.13854019763,
('price', 'prix'): 324162.66684322944,
('price', 'departement'): 466290.81724082783,
('price', 'annee'): 454736.63137143303,
('price', 'kilometrage'): 117557.09720242623}
I want to filter only on the first part of my key which is a tuple. In other words I want to get this result if I specify in my code 'Year':
{('Year', 'prix'): 130546.87449454193,
('Year', 'departement'): 11591.47409694357,
('Year', 'annee'): 34.28496633835407,
('Year', 'kilometrage'): 414330.13854019763}
I reached my result, but only after multiple lines of code. I am wondering if there is a way to do it smoothly.
Thanks in advance
You can use dict comprehension:
# Suppose you have your dict stored in dct
# The line below returns a filtered dictionary, including keys with first tuple element 'Year'
{key: dct[key] for key in dct.keys() if key[0]=='Year'}

Extract values from web service JSON response with JSONPath

I have a JSON response from web service that looks something like this :
[
{
"id":4,
"sourceID":null,
"subject":"SomeSubjectOne",
"category":"SomeCategoryTwo",
"impact":null,
"status":"completed"
},
{
"id":12,
"sourceID":null,
"subject":"SomeSubjectTwo",
"category":"SomeCategoryTwo",
"impact":null,
"status":"assigned"
}
]
What I need to do is extract the subjects from all of the entities by using JSONPATH query.
How can I get these results :
Subject from the first item - SomeSubjectOne
Filter on specific subject value from all entities (SomeSubjectTwo for example)
Get Subjects from all entities
Goessner's orinial JSONPath article is a good reference point and all implementations more or less stick to the suggested query syntax. However, implementations like Jayway JsonPath/Java, JSONPath-Plus/JavaScript, flow-jsonpath/PHP may behave a little differently in some areas. That's why it can be important to know what implementation you are actually using.
Subject from the first item
Just use an index to select the desired array element.
$.[0].subject
Returns:
SomeSubjectOne
Specific subject value
First, go for any elements .., check those with a subject [?(#.subject] and use == '..' for comparison.
$..[?(#.subject == 'SomeSubjectTwo')]
Returns
[ {
"id" : 12,
"sourceID" : null,
"subject" : "SomeSubjectTwo",
"category" : "SomeCategoryTwo",
"impact" : null,
"status" : "assigned" } ]*
Get all subjects
$.[*].subject
or simply
$..subject
Returns
[ "SomeSubjectOne", "SomeSubjectTwo" ]

How to save a global variable with table format from NetLogo Behaviorspace

I have written a fairly complicated code for my ABM (634 agents having interactions, each having different variables some of which are lists with multiple values that are updated each tick). As I need to save the updated values for all agents, I have defined a global variable using table:make. This table has 634 keys (each key for one agent), and each key has a list of those values (from that agents-own list variable) for the correspondent agent. But when I use the name of this table to be reported as one of my outputs in Behavior Space, the result in csv file is a table with no keys and it has only a number in it: {{table: 1296}}. So, I was wondering how I could change this variable to be able to have all values.
If you're happy to do some post-processing with R or something after the fact, then table:to-list might be all you need. For example, with a simple setup example like:
extensions [ table ]
globals [ example-table ]
turtles-own [ turtle-list ]
to setup
ca
crt 3 [
set turtle-list ( list random 10 one-of [ "A" "B" "C" ] random 100 )
]
set example-table table:make
foreach sort turtles [
t ->
table:put example-table ( word "turtle_" [who] of t ) [turtle-list] of t
]
reset-ticks
end
And a to-report to clean each table item such that the first item is the key and all other items are the items in the list:
to-report easier-read-table [ table_ ]
let out []
foreach table:to-list table_ [ i ->
set out lput ( reduce sentence i ) out
]
report out
end
You can set up your BehaviorSpace experiment such that one of your reporters is that reporter, something like:
To get a .csv file like:
Where the reporter column outputs a list of lists that you can process how you like.
However, I probably wouldn't use the basic BehaviorSpace output for this, but instead have a call in the experiment to call a manual table output procedure. For example, using the csv extension to make this output-table procedure:
to output-table [ filename_ table_ ]
let out [["key" "col1" "col2" "col3"]]
foreach table:to-list table_ [ i ->
set out lput ( reduce sentence i ) out
]
csv:to-file filename_ out
end
This outputs a much more analysis-ready table if you're less comfortable cleaning the output of a list-of-lists that as far as I know is what you would get from the BehaviorSpace output. So, you can either call it at the end of your experiment, like:
To get a table like:
Which is a little nicer to deal with. You can obviously modify this to report more often if needed, for example:
which would output a table at each tick of the experiment (you can also do this in your code to make it a little easier).

Silverstripe combine filterAny and filter to have an OR with an AND in it

I have a question and maybe somebody can help me figure out what the best way would be to achieve the solution. What i wanted to do is the reverse of:
http://doc.silverstripe.com/framework/en/topics/datamodel#highlighter_745635
WHERE ("LastName" = 'Minnée' AND ("FirstName" = 'Sam' OR "Age" = '17'))
I want to get something along the lines of:
WHERE( ("LastName" = 'Minnée') OR ("FirstName" = 'Sam' AND "Age" = '17'))
Now i cannot find any way to achieve this effect seeing as i cannot add a filter within the filterAny
For now i am doing it with the get()->where( ... ) option but was more wondering with this question if their are alternative options without having to write normal SQL code.
As 'AND' has a higher priority it doesn't need to be in braces. You can just write it as:
WHERE( "LastName" = 'Minnée' OR "FirstName" = 'Sam' AND "Age" = '17')
But as far as I can tell on the first look there isn't a way to write this without using where(). Let us know if you find a way. For debuging you can display the generated SQL-Query by calling the function sql():
... get()->where( ... )->sql();

Resources