assistance needed constructing JSONata query - jsonata

I am trying to construct a JSONata query using the try.jsonata.org Invoice data.
The query I am trying to pose is select distinct OrderID where Order.Product.Price is < 50?
I have not been able to figure out how to do this using the predicate in square brackets notation ... my attempts have been thwarted when I try to get past the $.Account.Order.Product array.
Using $map and $reduce I was able to come up with this rather complex solution ... which still doesn't correctly handle duplicate OrderIDs. (I see that the issue of duplicate removal has been requested here)
Q: What is the proper way to express this query in JSONata?

I think this does what you need:
Account.Order[Product.Price.($ < 50)].OrderID
The expression in the predicate, which gets tested for each Order, will generate an array of Booleans (one for each Product.Price). The resulting predicate will evaluate to true if any of the Booleans within that array are true, due to the semantics of the $boolean function which is implicitly applied.
Overall, the expression will return the OrderID for every Order which has at least one Product whose Price is less than 50

Related

Mapbox - setFilter expression for 'Contains' name within array of possible values

I'm trying filter my Mapbox layer (mapboxgl) to return just places that start with say 'North', 'South, 'East' or 'West'.
My places are in geojson data as a property.
I'm using map.setFilter with an expression to filter the geojson.
Example:
map.setFilter('markers', ["all",filter1,filter2]);
Where filter2 is a simple check on if the place is 'open' or 'closed' and filter1 is my main filter expression explained below.
The main issue is that the name of the place needs to START with one of these values.
So far I can do this IF the strings to check are all the same length by grabbing the length of the strings and then filtering by that substring of the name.
But this doesn't work (obviously) when I have words that are not the same length.
This is pretty simple in most other languages, but my brain cant figure out this in mapbox's expression filters for some reason!
Here's what I have so far (please excuse the poor code quality here, I'm not a professional coder!!):
//the array data to check for a match
filterArray = ['North','South','East','West'];
//checks first values length - not ideal!
var lengthToCheck = filterArray[0].length;
//apply it to the filter to only return ones starting with X
filter1 = ['in', ['slice',['to-string', ['get', 'name']],0,lengthToCheck], ['literal', filterArray]];
I have to slice the name of the place as it might be for example 'Northampton', which wont be found within the array value[0] being 'North'.
This is equally as bad code for the 'East' values as the name slice is going to be 5 characters, so it will be trying something like 'Eastb' (Eastbourne) within the array value 'East' which just wont work.
It would be good if I could some how flip this round so the filter can check the values in the array within the Name, but I can't figure this out!
Is there a way to do that or is there a magic expression feature I'm missing that would solve this problem?
I'm also going to have the same problem with a 'Contains' type check of an array of values too, but I'll cross that bridge once I figure this part out!
Any help appreciated (before I go putting in some convoluted workaround!).

Spring Data JPA fetching list always returns at least a single result

I've noticed a slight problem with how my API is working where I'm using Spring Data JPA.
My query looks something along the lines of:
#Query("SELECT p.id AS id, COUNT(l) AS likes FROM Post p LEFT JOIN Like l ON l.post = p WHERE p.location.id = ?1")
My actual query is bigger, this this contains everything necessary to explain what the issue is. This query will return a list, but assume the location does not exist, it should return null or an empty list, correct? Oh, how wrong you are, my sweet summer child!
This query will instead always return a list of at least one element, regardless of whether or not there are any posts linked to said location.
[{"id": null, "likes": 0}]
That is what the result looks like when serialized to JSON. I am not quite sure what to do about this little predicament, as I obviously don't want to return a list with faulty data, but needing to use processing to filter out duds also seems dumb and unnecessary.
Is there any way to prevent this that I've yet to find? If it is of any relevance, I am using projections currently for my responses.
What I've tried so far:
Adding a not null condition for fields. Does not work, ignored by COUNT.
Adding constraints to all fields #NotNull. Does not work, will still become null.
For what it's worth, I've tried different kinds of joins, though anything but LEFT JOIN doesn't make much sense.
I haven't been able to find any other case which resembles this either, although it most likely exists, but is drowned out by everything else. I'm not quite sure what can be done in this regard, so I'm curious if it's just a quirk with the framework, or if there is an actual solution.
It might be possible to solve through native queries, but I would prefer not to use them.
I'm no SQL expert but I believe that a left join will give you this result if the ID does not exist.
Have you run the query in your DB? Doesn't it give you one row in your result set for IDs that do not exist?
I believe this is intended to say there is a 0 match.
You might want to validate your query before running it. Meaning checking that the location exists first.
As the issue is inherently due to a COUNT and CASE keyword in my real query, resulting in there always being at least one row, and I can't find any method of doing this automatically, the solution I've used is the following:
List<Item> items = repository.customQuery(id);
if (0 < items.size() && null == items.get(0).getId()) {
items.remove(0);
}
The first condition is arbitrary as I know there is always at least one entry, but is done just as a safety measure. A try-catch block would do the trick as well. In the case where you use a primitive int instead of Integer, you'd need to initialize the value in the constructor to something which would normally never be present in the database, such as -1.
If anyone knows of a better method, I'd love to know about it.

In Wolfram Mathematica, who do I query the result of a Counts operation efficiently and conveniently?

EDIT At the suggestion of #HighPerformanceMark, I've moved the question to mathematica.stackexchange.com: my question, so I attempted to close the question here. But SO doesn't allow me to do it properly, hence this up-front warning.
Setup
Say, I'm given a dataset, like the one below:
titanic = ExampleData[{"Dataset", "Titanic"}]; titanic
Answering with:
And I want to count the occurrences of any combination between { "1st", "2nd"} and {"female", "male"}, using the Counts operator on the dataset, like:
genderclasscounts = titanic[All, {"class", "sex"}][Counts]
Problem statement
This is not a "flat" dataset and I don't have a clue how to query in the usual way, like:
genderclasscount[Select[ ... ], ...]
The resulting dataset doesn't provide "column" names to be used as parameters in the Select nor can I refer to the number representing the count by a name.
And I've no clue how to express an Association as a value in a Select!?
Furthermore, try genderclasscount[Print], this demonstrates the values presented to the operation over this dataset are just numbers!
An unsatisfactory attempt
Of course, I can "flatten" the Counts result, by doing something horrific and inefficient like:
temp = Dataset[(row \[Function]
AssociationThread[{"class", "sex", "count"} -> row]) /# (Nest[
Normal, genderclasscounts, 3] /.
Rule[{Rule["class", class_], Rule["sex", sex_]},
count_] -> {class, sex, count})]
In this form it is easy to query a count result:
First#temp[Select[#class == "1st" \[And] #sex == "female" &], "count"]
Question
So, my questions are
How can I query the (immediate) result of the Count operation in a convenient and efficient fashion, like using a Select operation on the resulting dataset? Or, if that is not possible;
Is there an efficient and convenient transformation of the Counts result dataset possible facilitating such a query? With "convenient" I mean, for example, that you just provide the dataset and the transformation handles the rest. So, not something like I've shown above in my unsatisfactory "solution" ;-)
Thanks for reading this far and I'm looking forward to anwsers and inspiration.
/#nanitous

Selecting multiple results from XQUERY query

I am trying to select multiple columns from a query, but so far, I can only manage to select one. So I'm basically stuck with either selecting one, or all of them.
Here's my expression, what I got so far, which select only (1) column:
let $y := doc("http://en.wikipedia.org/wiki/List_of_deaths_on_eight-thousanders")//table[preceding-sibling::h2//span[string() = "K2"]][1]
return $y/tr/td[2]/string()
I would love some explanation of how one would go about doing this, since there's almost no documentation of this lovely language.
How would you like the result to be returned? You could construct new elements, or concatenate strings. There are many ways that this could be accomplished.
Here's one way to get comma-separated values:
return $y/tr/fn:string-join( (td[2] | td[4]), ", " )
You can try it on zorb.io.
Update
(td[2] | td[4]) selects both elements, and passes them, as a sequence, to fn:string-join(). | is the XQuery union operator (and can be substituted for the keyword).
As far as documention, the functx site documents the standard library (all fn-prefixed functions), and has useful examples. And the specs are surprisingly readable.

Prefix the result of a XPATH query

I use libxmljs to parse some html.
I have a xpath query which has an "or" conjunction to retrieve basically the information of two queries
Example
doc.find("//div[contains(#class,'important') or contains(#class,'overdue')]")
this returns all the divs with either important or overdue...
Can I prefix or see within my result set which comes from which condition?
The result could be an array with an index for the match 0 for the first condition and 1 for the 2... Is this possible...
Or how can I find out which result comes from which query condition...
Thanks for any help...
P.S.: this is a simplified exampled of a sequence of elements which either have an important or an overdue item ... both, one or none of them... So I cannot go by looking for every second entry ... etc
This is the result I want to get...
message:{},
message:{
.....
important: "some immportant text",
overdue: "overdue date,
.....
}
There is no way to know which clause of an or XPath query caused a particular result to be included. It's simply not information that's kept around.
You'll either need to do entirely separate queries for important and overdue, or do one large query to get the entire result set (as you are now) and then further test each result's class to find out which one it is.

Resources