Using RQL filter documents by condition on nested array in RavenDB 4.0+ - ravendb

In RavenDB 4.0+ for a given Sample Northwind database (which is also available at http://live-test.ravendb.net/), what RQL queries one may use to:
Get Orders in which at least one of the Lines has Discount == 0?
Get Orders in which all the Lines have Discount != 0?
Get Orders in which at least one of the Lines has Discount != 0?
Get Orders in which all the Lines have Discount == 0?
Here's a sample document structure:
{
"Company": "companies/85-A",
"Employee": "employees/5-A",
"Freight": 32.38,
"Lines": [
{
"Discount": 0,
"PricePerUnit": 14,
"Product": "products/11-A",
"ProductName": "Queso Cabrales",
"Quantity": 12
},
{
"Discount": 0,
"PricePerUnit": 9.8,
"Product": "products/42-A",
"ProductName": "Singaporean Hokkien Fried Mee",
"Quantity": 10
},
{
"Discount": 0,
"PricePerUnit": 34.8,
"Product": "products/72-A",
"ProductName": "Mozzarella di Giovanni",
"Quantity": 5
}
],
"OrderedAt": "1996-07-04T00:00:00.0000000",
"RequireAt": "1996-08-01T00:00:00.0000000",
"ShipTo": {
"City": "Reims",
"Country": "France",
"Line1": "59 rue de l'Abbaye",
"Line2": null,
"Location": {
"Latitude": 49.25595819999999,
"Longitude": 4.1547448
},
"PostalCode": "51100",
"Region": null
},
"ShipVia": "shippers/3-A",
"ShippedAt": "1996-07-16T00:00:00.0000000",
"#metadata": {
"#collection": "Orders",
"#flags": "HasRevisions",
"#id": "orders/1-A",
"#last-modified": "2018-07-27T12:11:53.0447651Z",
"#change-vector": "A:417-EKrWjfz5kESi6lp7Nf442Q",
"#index-score": 1
}
}
I managed to find out some answers only for 1 and 2:
Get Orders in which at least one of the Lines has Discount == 0?
from Orders where Lines[].Discount == 0
from Orders where Lines[].Discount IN (0)
from Orders where Lines[].Discount ALL IN (0)
Get Orders in which all the Lines have Discount != 0?
from Orders where Lines[].Discount != 0

Related

Find authors with age under 40 in my postgresql table

I have the following table with one row. I have tried to query this table to return authors under the age of 40 and have been unable to do so.
CREATE TABLE bookstuff (
data JSON
);
insert into bookstuff(data)
VALUES('
{
"the_books": {
"publishers": [
{
"name": "Dunder Mifflin",
"address": "Scranton, PA",
"country": "USA",
"CEO": "David Wallace"
},
{
"name": "Sabre",
"address": "Tallahassee, FL",
"country": "USA",
"CEO": "Jo Bennett"
},
{
"name": "Michael Scott Paper company",
"address": "Scranton, PA",
"country": "USA",
"CEO": "Michael Gary Scott"
},
{
"name": "Vance Refrigeration",
"address": "Scranton, PA",
"country": "USA",
"CEO": "Bob Vance"
}
],
"authors": [
{
"id": 1,
"name": "Michael Scott",
"age": 45,
"country": "USA",
"agentname": "Jan Levinson",
"books_written": "book1"
},
{
"id": 2,
"name": "Jim Halpert",
"age": 35,
"country": "USA",
"agentname": "Pam Beesly",
"books_written": "book3"
},
{
"id": 3,
"name": "Dwight Schrute",
"age": 40,
"country": "USA",
"agentname": "Angela Martin",
"books_written": "book2"
},
{
"id": 4,
"name": "Pam Halpert",
"age": 35,
"country": "USA",
"agentname": "Angela Martin",
"books_written": "book4"
}
],
"books": [
{
"isbn": "book1",
"title": "The Dundies",
"price": 10.99,
"year": 2005,
"publishername": "Dunder Mifflin"
},
{
"isbn": "book2",
"title": "Bears, Beets, Battlestar Galactica",
"price": 8.99,
"year": 2006,
"publishername": "Dunder Mifflin"
},
{
"isbn": "book3",
"title": "The Sabre Store",
"price": 12.99,
"year": 2007,
"publishername": "Sabre"
},
{
"isbn": "book4",
"title": "Branch Wars",
"price": 14.99,
"year": 2015,
"publishername": "Sabre"
}
]
}
}');
I have tried the following query to get the author's age
SELECT data->'the_books'->'authors'
FROM bookstuff
WHERE (data->'the_books'->'authors'->>'age')::integer > 40;
I expect it to return two values 'Jim halpert' and 'pam halpert' but instead I get no result back, not even null.
I have also tried this query, just to see if i could get anything back at all from the table and still no results:
SELECT data->'the_books'->'authors'
FROM bookstuff
where (data->'the_books'->'authors'->'name')::jsonb ? 'Michael Scott';
I'm new to postgresql, is there a different way I should be going about this?
Using json_array_elements:
select (v -> 'name')#>>'{}' from bookstuff b
cross join json_array_elements(b.data -> 'the_books' -> 'authors') v
where ((v -> 'age')#>>'{}')::int < 40
See fiddle
Another option, slightly more verbose:
select distinct(author->>'name') as author_name from
(select json_array_elements(b.data->'the_books'->'authors') author from bookstuff b) author
where (author->>'age')::int < 40
The distinct might be unnecessary if you really just have one database row and no duplicates in the authors array of that row.
Three considerations of why your final solution doesn't work
where filters out rows - this happens before the 'select'. the row contains everything in this case.
'?' predicate matches an array containing your choosen value "Does the key/element string exist within the JSON value?" You don't have a simple array here array->'key' doesn't pick that attribute into a new array
your select projection isn't called however it was it would contain the whole array (remember where doesn't transform just filters out rows)

Problem with using of FOR JSON AUTO in SQL Server

I am using FOR JSON AUTO in SQL server database, to convert my query's result to the JSON format.
in my query, I joined order table to two other tables.
SELECT
orders.[Code], orders.[Total], orders.[Discount],
customer.[Name], customer.[PhoneNumber],
store.[Name], store.[Address]
FROM
Orders orders
INNER JOIN
Customers customer ON (orders.[CustomerID] = customer.[ID])
INNER JOIN
Stores store ON (orders.[StoreID] = store.[ID])
FOR JSON AUTO
Result:
[
{
"Code": "1528",
"Total": 5000,
"Discount": 20,
"customer": [
{
"Name": "Alex",
"PhoneNumber": "(548) 123-5555",
"store": [
{
"Name": "Apple",
"Address": "E. Santa rd"
}
]
}
]
},
{
"Code": "1687",
"Total": 3000,
"Discount": 10,
"customer": [
{
"Name": "John",
"PhoneNumber": "(226) 354-7896",
"store": [
{
"Name": "Sony",
"Address": "W. Atlantic ave"
}
]
}
]
}
]
But it's not correct, because in this scenario customer and store are sibling and they have same parent, and both of them joined with the order table directly, correct JSON must be such as this:
[
{
"Code": "1528",
"Total": 5000,
"Discount": 20,
"customer": [
{
"Name": "Alex",
"PhoneNumber": "(548) 123-5555"
}
],
"store": [
{
"Name": "Apple",
"Address": "E. Santa rd"
}
]
},
{
"Code": "1687",
"Total": 3000,
"Discount": 10,
"customer": [
{
"Name": "John",
"PhoneNumber": "(226) 354-7896"
}
],
"store": [
{
"Name": "Sony",
"Address": "W. Atlantic ave"
}
]
}
]
how can I do that? Are there any option for this in SQL? (I don't want to use inner select.)
If there are one-to-one relationships between Orders and Customer and between Orders and Store then you can make the desired output by using PATH option and dot-separated column names:
SELECT
orders.[Code], orders.[Total], orders.[Discount],
customer.[Name] AS [Customer.Name], customer.[PhoneNumber] AS [Customer.PhoneNumber],
store.[Name] AS [Store.Name], store.[Address] AS [Store.Address]
FROM
Orders orders
INNER JOIN
Customers customer ON (orders.[CustomerID] = customer.[ID])
INNER JOIN
Stores store ON (orders.[StoreID] = store.[ID])
FOR JSON PATH
But if there are one-to-many relationships then you have to use nested queries:
SELECT
orders.[Code], orders.[Total], orders.[Discount],
(SELECT [Name], [PhoneNumber] FROM Customers WHERE Customers.ID=Orders.CustomerID FOR JSON AUTO) AS Customers,
(SELECT [Name], [Address] FROM Stores WHERE Stores.ID=Orders.StoreID FOR JSON AUTO) AS Stores
FROM
Orders orders
FOR JSON AUTO

I'm getting the location_id as null in shopify order api

I created an order through shopify admin and added the customer details , when i executes the orders.json api , I'm getting location_id ="null"
Now i'm in need of location id to update the fulfillment status.
How to update the location id for an order if possible .This is my response when i created an order .
{
"orders": [
{
"id": 568323571800,
"email": "sample_test_123_gmail#gmail.com",
"closed_at": null,
"created_at": "2018-08-02T15:41:06+05:30",
"updated_at": "2018-08-02T15:46:06+05:30",
"number": 9,
"note": "",
"token": "a666eb3aea251cc585afc006cbf5b315",
"gateway": "Cash on Delivery (COD)",
"test": false,
"total_price": "200.00",
"subtotal_price": "200.00",
"total_weight": 100,
"total_tax": "0.00",
"taxes_included": false,
"currency": "INR",
"financial_status": "pending",
"confirmed": true,
"total_discounts": "0.00",
"total_line_items_price": "200.00",
"cart_token": null,
"buyer_accepts_marketing": false,
"name": "#1009",
"referring_site": null,
"landing_site": null,
"cancelled_at": null,
"cancel_reason": null,
"total_price_usd": "2.92",
"checkout_token": null,
"reference": null,
"user_id": 23090102360,
"location_id": null,
location ID is tied to your inventory. First off, ensure you have set a location for your inventory. Second, make sure Shopify is set as your inventory management provider. If you now create an order for items managed by Shopify, you might see a location ID. Your test of creating a draft order like that might also not be fully integrated yet with Shopify locations? What happens when you book an order using the front end and not the API?
location_id on an order will return null unless the order is made from a Shopify POS location in which case it will return the location_id associated with that location.
See the guide on fulfillments: https://help.shopify.com/en/api/guides/managing-fulfillments
To get locationId in order, need to pass inventoryQuantities input with location id and available quantity in productCreate Mutation.Then You will get locationId in order
{
"input": {
"title": "Demo Product",
"descriptionHtml": "des",
"productType": "type",
"vendor": "vendor",
"handle": "abc1",
"tags": ["tag1", "tag2"],
"variants": [
{
"title": "small",
"price": 100,
"compareAtPrice": 110,
"position": 1,
"inventoryQuantities": {
"availableQuantity": 100,
"locationId": "gid://shopify/Location/55274340513"
},
"inventoryItem": {
"cost": 200,
"tracked": true
}
}
]
}
}
You can find location_id from the /admin/api/2021-04/locations.json API.
You will get response like this:
{
"locations": [
{
"id": location_id,
"name": "location_name",
"address1": "location_address",
"address2": null,
"city": "Faisalabad",
"zip": "38000",
"province": "",
"country": "PK",
"phone": "",
"created_at": "2021-02-25T15:34:18+05:00",
"updated_at": "2021-02-25T15:34:20+05:00",
"country_code": "PK",
"country_name": "Pakistan",
"province_code": null,
"legacy": false,
"active": true,
"admin_graphql_api_id": "gid://shopify/Location/location_id",
"localized_country_name": "Pakistan",
"localized_province_name": null
}
]
}

array of json object

database screenshot [
{
"id": "901651",
"supplier_id": "180",
"price": "18.99",
"product_id": "books",
"name": "bookmate",
"quantity": "1"
},
{
"id": "1423326",
"supplier_id": "180",
"price": "53.99",
"product_id": "books",
"name": "classmate",
"quantity": "5"
}
]
"
[{"id":"3811088","supplier_id":"2609","price":"22.99","product_id":"book","name":"classmate","quantity":"10"}]"
I have my purchased books details stored in an array of json object in a field named items in table purchase_list. This corresponds to only one order.Field may contain single or multiple orders. There are multiple orders like this. how can i get the total number of each type of book purchased and the type of books only using pgsql query to generate jasper report. for eg: classmate:15, bookmate:1
you can unnest array and aggregate it:
t=# with c(j) as (values('[
{
"id": "901651",
"supplier_id": "180",
"price": "18.99",
"product_id": "books",
"name": "bookmate",
"quantity": "1"
},
{
"id": "1423326",
"supplier_id": "180",
"price": "53.99",
"product_id": "books",
"name": "classmate",
"quantity": "5"
}
,{"id":"3811088","supplier_id":"2609","price":"22.99","product_id":"book","name":"classmate","quantity":"10"}]'::jsonb))
, agg as (select jsonb_array_elements(j) jb from c)
, mid as (select format('"%s":"%s"',jb->>'name',sum((jb->>'quantity')::int)) from agg group by jb->>'name')
select format('{%s}',string_agg(format,','))::jsonb from mid;
format
--------------------------------------
{"bookmate": "1", "classmate": "15"}
(1 row)
looks ugly, but gives the idea

Get products of an order with Spree API

I simply want to get all the orders of my Spree e-commerce system, with all products the user bought in an order. I see I can grab all orders, all shipments, but there is no information about a "complete" query that includes products a user bought.
There is a way to do that ?
GET /api/v1/orders is a paginated query which respons should look something like that:
{
"orders": [
{
"id": 1,
"number": "R335381310",
"item_total": "100.0",
"display_item_total": "$100.00",
"total": "100.0",
"display_total": "$100.00",
"state": "cart",
"adjustment_total": "-12.0",
"user_id": null,
"created_at": "2012-10-24T01:02:25Z",
"updated_at": "2012-10-24T01:02:25Z",
"completed_at": null,
"payment_total": "0.0",
"shipment_state": null,
"payment_state": null,
"email": null,
"special_instructions": null,
"total_quantity": 1,
"token": "abcdef123456",
"line_items": [
],
"adjustments": [
],
"payments": [
],
"shipments": [
]
}
],
"count": 25,
"pages": 5,
"current_page": 1
}
Each Order contains line_items, which are products that you are looking for.
Source: http://guides.spreecommerce.org/api/orders.html