Only select shortest value for column with multiple values on Wikidata query - filter

I have the following query:
SELECT ?admin ?name ?abbr
WHERE {
VALUES ?admin { wd:Q771 }
?admin wdt:P131 ?country;
wdt:P17 ?country.
OPTIONAL { ?admin wdt:P1813 ?alias. }
SERVICE wikibase:label {
bd:serviceParam wikibase:language "en".
?admin rdfs:label ?name.
?alias rdfs:label ?abbr.
}
}
This retrieves the administration in VALUES with its English name and abbrevations, if available. For example:
admin
name
abbr
wd:Q771
Massachusetts
MA
wd:Q771
Massachusetts
Mass.
Now I would like to filter it such that only the shortest abbreviation is displayed. For the above output, for example, I would only get one record, the one with MA. How can I accomplish this?

Related

How to add filter to nested objects in GraphQL the GraphQL way?

Say I want to query an object tree like this:
query UsersWithOrgs {
users {
nodes {
firstName
lastName
orgMemberships {
nodes {
joinedAt
organization {
name
foundedAt
location {
city
country
}
}
}
}
}
}
}
Now say I want to filter for only the users where the org they joinedAt <= 6 months ago, or only the users where the org they joined is in England.
query UsersWhereJoinedRecently {
users {
nodes {
firstName
lastName
orgMemberships(joinedAt: { lte: "2022/03/12" }) {
nodes {
joinedAt
organization {
name
foundedAt
location {
city
country
}
}
}
}
}
}
}
query UsersWhereOrgInEngland {
users {
nodes {
firstName
lastName
orgMemberships {
nodes {
joinedAt
organization {
name
foundedAt
location(country: "England") {
city
country
}
}
}
}
}
}
}
Is this the "GraphQL way" of defining filters on nested objects? Or should the filters be hoisted up somehow?
Based on the definitions above, I would instead expect UsersWhereJoinedRecently to return all users in the app, but orgMemberships would be filtered to only include those after the joinedAt date. Likewise, I would expect UsersWhereOrgInEngland to return all users with all their orgs, but only return the location for the org if the country is "England". That is not at all what I want, I want only the users where if that deeply nested condition is false, not to return the user. What is the appropriate way people handle this situation?
To me there are two passes in the overall query:
Joins and Wheres.
Projection.
First, we must fetch all users where the deeply nested condition is true. Then given those top-level IDs for the user, we fetch the projected schema.
So first:
// userIds =
select id from users
inner join memberships on memberships.userId = users.id
where memberships.joinedAt <= "2022/03/12"
Then:
select firstName, lastName from users where id in userIds
select joinedAt, orgId from orgMemberships where userId in userIds and joinedAt <= "2022/03/12"
... select from each of the other tables.
... then build into tree and return to client.
Same with the other query.
So because of these two seemingly completely separate phases, it makes me think that all filtering should be passed in at the top level in some fashion in GraphQL. Like:
query UsersWhereJoinedRecently {
users(membershipJoinedAt: { lte: "2022/03/12" }) {
nodes {
firstName
lastName
orgMemberships {
nodes {
joinedAt
organization {
name
foundedAt
location {
city
country
}
}
}
}
}
}
}
Is that correct, is that the recommended practice? Or what is recommended practice in these sorts of "filter by nested objects" scenarios?

GraphQL How to get all countries based on a selected continent code

I am using the following GraphQL schema and want to find out how to get all the countries based on the continent code.
https://countries.trevorblades.com/
query GetCountriesByContinent($code: String!) {
countries(filter: {
continent: {
???
}
})
}
Any ideas?
UPDATE: The following code works but I am not sure how continent is match against the code.
query GetCountriesByContinent($code: String!) {
countries(filter: {
continent: { eq: $code }
}) {
name
}
}
UPDATE 2:
It might be that behind the scene when you compare a type with something it always compare using the ID field.
To better understand your query let's break it down
countries(filter: {
continent: { eq: $code }
})
countries - find all countries
filter - filtered by
continent - continent (field)
eq - equals to
$code - code (passed as argument)
In this API field code acts as an ID so behind the scenes they compare by continent.code. That logic of comparison and filtering is happening on the server-side implementation. The developer of that API can choose how he wants to implement comparison
You can also explore docs and schema on the right-side panel in Grahpql Playground and you can see possible options:
input CountryFilterInput {
code: StringQueryOperatorInput
currency: StringQueryOperatorInput
continent: StringQueryOperatorInput
}
That means you can filter countries by code currency and continent
input StringQueryOperatorInput {
eq: String
ne: String
in: [String]
nin: [String]
regex: String
glob: String
}
eq: is exactly the filter value.
ne: is anything except for the filter value.
in: matches any element in given array
nin: matches none of the elements in given array
lt: is lower than the filter value
lte: is lower than or equal to the filter value
gt: is greater than the filter value
gte: is greater than or equal to the filter value
regex: matches given JavaScript regex
glob: matches given micromatch pattern
It looks like query filters used in Gatsby to get more details
Reference docs: https://www.gatsbyjs.com/docs/query-filters/#supported-comparators

Query the product using Product Tag

I want to query the product using product tag, but it returned similar product tags with the given tags. I Refer some other references, it denotes the tag are tokenized field so it will return product, if any equality exists in the tags. but i want know if any possibility are there to retrieve the exact tag products
Query
query Myquery{
products(first:10, query: "tag:Switches variants.price:>=2335 variants.price:<=3000") {
edges {
node {
id
tags
variants(first:10)
{
edges
{
node
{
price
}
}
}
}
cursor
}
pageInfo {
hasNextPage
hasPreviousPage
}
}
}
Above query returns tag 'Switches' and 'Switches & Sockets' but i need tag with 'Switches' alone
You can add an exclusion but you need to know what to exclude e.g.:
{
products(first:10, query: "tag:Switches -tag:Sockets") {
edges {
node {
id
tags
variants(first:10)
{
edges
{
node
{
price
}
}
}
}
cursor
}
pageInfo {
hasNextPage
hasPreviousPage
}
}
}
You understand that tags are a string right? So if you search for the string Switches you will get back Switches, and anything else in the string. So you have the extra step of further processing your results. Split on comma into an array, and only return the products where the filter condition is equal to Switches alone.

SPARQL INSERT/DELETE

I need some help to write my update query.
DELETE {
?contactInfo vivo:freeTextValue5 ?o .
}
INSERT {
?contactInfo vivo:freeTextValue5 "new_url"^^<http://www.w3.org/2001/XMLSchema#string> .
}
WHERE {
?contactInfo vivo:freeTextValue5 "old_url"^^<http://www.w3.org/2001/XMLSchema#string> .
}
Can you please let me know what is wrong with this "update" query?
I'm guessing that your problem is that this update adds a new triple, but does not remove the old one.
The reason is that your DELETE clause contains an unbound variable: ?o. This is not allowed - or at least what happens is that patterns with unbound variables are simply ignored by the SPARQL engine. So your DELETE won't actually remove any triples. The variable ?o needs to be bound to a value in your WHERE clause.
One way to fix this is to just replace ?o with the specific value:
DELETE {
?contactInfo vivo:freeTextValue5 "old_url"^^<http://www.w3.org/2001/XMLSchema#string> .
}
INSERT {
?contactInfo vivo:freeTextValue5 "new_url"^^<http://www.w3.org/2001/XMLSchema#string> .
}
WHERE {
?contactInfo vivo:freeTextValue5 "old_url"^^<http://www.w3.org/2001/XMLSchema#string> .
}
More generally, you can use a VALUES clause to bind ?o to a value, like this:
DELETE {
?contactInfo vivo:freeTextValue5 ?o.
}
INSERT {
?contactInfo vivo:freeTextValue5 "new_url"^^<http://www.w3.org/2001/XMLSchema#string> .
}
WHERE {
VALUES ?o { "old_url"^^<http://www.w3.org/2001/XMLSchema#string> }
?contactInfo vivo:freeTextValue5 ?o.
}
This is perhaps the better approach as it makes it easier to extend your update to different values for ?o.

optimizing search query with criteria combination

i have a list of search inputs ( 4 search inputs ) , as criteria i have to do a combination to get a list of books ( by author , by publish date , by name , by number of pages )
this is the code
if((author!="") && (date!="")&&(name!="")&&(numPages!="")){
//query getting the books with th 4 criteria
}else{ if((author!="") &&(name!="")&&(numPages!="") ){
//query getting the books with th 3 criteria
}
} etc
is there a better way to do the combination of those criteria
EDIT
this is one of the queries with criteria :
def invoiceListbyAll=Invoice.createCriteria().list {
eq("author", authorObj)
eq("name", name)
eq("numPages", numPages)
}
You could write it as:
def invoiceListbyAll=Invoice.createCriteria().list {
// from your code I assume that all parameter are strings
if (author) { // groovy empty strings act as boolean false
eq("author", authorObj)
}
if (name) {
eq("name", name)
}
if (numPages) {
eq("numPages", numPages)
}
}

Resources