N1ql SUM on UNNEST Array
I have a single bucket (Couchbase Community edition 6.5) consisting of the following documents:
FishingDoc
{
"boatIds": ["boatId_1","boatId_2","boatId_3"],
"areaIds": ["areaId_1","areaId_2","areaId_3"],
"total": 10,
"date": "2021-05-13T00:00:00Z",
"type": "fishing"
},
{
"boatIds": ["boatId_1","boatId_3"],
"areaIds": ["areaId_2","areaId_3"],
"total": 25,
"date": "2021-05-15T00:00:00Z",
"type": "fishing"
}
RiverDoc
{
"_id": "areaId_1",
"size": 5,
"type": "river"
},
{
"_id": "areaId_1",
"size": 10,
"type": "river"
},
{
"_id": "areaId_1",
"size": 15,
"type": "river"
}
BoatDoc
{
"_id": "areaId_1",
"name": "Small Boat",
"type": "boat"
},
{
"_id": "areaId_1",
"name": "Medium Boat",
"type": "boat"
},
{
"_id": "areaId_1",
"name": "Large Boat",
"type": "boat"
}
I need a query where I can get all of the fishing docs broken up per river and per boat. I got this working using the UNNEST operator in the following query:
SELECT river.size,
boat.name,
fishing.total
FROM bucket_name fishing
UNNEST fishing.riverIds AS river
UNNEST fishing.boatIds AS boat
WHERE fishing.type = "fishing"
But the problem in this query is that the total value in the above query is the total for the entire fishing object.
I need to get the total, relative to the size of the unnested river. So I need to join in and sum the total of all the rivers for the fishing object and get the specific river's size relative to the total.
Here is the select statement I have in mind but I have no idea on how to actually write the correct query:
SELECT river.size,
boat.name,
river.size/SUM( fishing.riverIds[0].size, fishing.riverIds[1].size, fishing.riverIds[2].size ) * fishing.total
FROM bucket_name fishing
UNNEST fishing.riverIds AS river
UNNEST fishing.boatIds AS boat
WHERE fishing.type = "fishing"
INSERT INTO default VALUES ("f01", { "boatIds": ["boatId_1","boatId_2","boatId_3"], "areaIds": ["areaId_1","areaId_2","areaId_3"], "total": 10, "date": "2021-05-13T00:00:00Z", "type": "fishing" });
INSERT INTO default VALUES ("f02", { "boatIds": ["boatId_1","boatId_3"], "areaIds": ["areaId_2","areaId_3"], "total": 25, "date": "2021-05-15T00:00:00Z", "type": "fishing" });
INSERT INTO default VALUES ("areaId_1", { "_id": "areaId_1", "size": 5, "type": "river" });
INSERT INTO default VALUES ("areaId_2", { "_id": "areaId_2", "size": 10, "type": "river" });
INSERT INTO default VALUES ("areaId_3", { "_id": "areaId_3", "size": 15, "type": "river" });
INSERT INTO default VALUES ("boatId_1", { "_id": "boatId_1", "name": "Small Boat", "type": "boat" });
INSERT INTO default VALUES ("boatId_2", { "_id": "boatId_2", "name": "Medium Boat", "type": "boat" });
INSERT INTO default VALUES ("boatId_3", { "_id": "boatId_3", "name": "Large Boat", "type": "boat" });
SELECT ARRAY {"size": f.river.[v], "name": f.boat.[f.boatIds[pos]], "total": f.total*f.river.[v]/ARRAY_SUM(OBJECT_VALUES(f.river))}
FOR pos:v IN f.areaIds END AS distribution
FROM (SELECT d.*,
OBJECT v._id:v.size FOR v IN (SELECT r._id, r.size FROM default AS r USE KEYS d.areaIds) END AS river,
OBJECT v._id:v.name FOR v IN (SELECT b._id, b.name FROM default AS b USE KEYS d.boatIds) END AS boat
FROM default AS d
WHERE d.type = "fishing") AS f;
{
"requestID": "fbe127b4-2ebb-4b01-a8a1-0bfe5310ed42",
"signature": {
"distribution": "array"
},
"results": [
{
"distribution": [
{
"name": "Small Boat",
"size": 5,
"total": 1.6666666666666667
},
{
"name": "Medium Boat",
"size": 10,
"total": 3.3333333333333335
},
{
"name": "Large Boat",
"size": 15,
"total": 5
}
]
},
{
"distribution": [
{
"name": "Small Boat",
"size": 10,
"total": 10
},
{
"name": "Large Boat",
"size": 15,
"total": 15
}
]
}
],
"status": "success",
"metrics": {
"elapsedTime": "6.946602ms",
"executionTime": "6.881065ms",
"resultCount": 2,
"resultSize": 730,
"serviceLoad": 2
}
}
OR
SELECT river AS SectionSize,
f.total*(river/ARRAY_SUM(f.sections)) AS total,
f.boats[UNNEST_POS(river)] AS name
FROM (SELECT d.total,
(SELECT RAW r.size FROM default AS r USE KEYS d.areaIds) AS sections,
(SELECT RAW b.name FROM default AS b USE KEYS d.boatIds) AS boats
FROM default AS d
WHERE d.type = "fishing") AS f
UNNEST f.sections AS river;
{
"results": [
{
"SectionSize": 5,
"name": "Small Boat",
"total": 1.6666666666666665
},
{
"SectionSize": 10,
"name": "Medium Boat",
"total": 3.333333333333333
},
{
"SectionSize": 15,
"name": "Large Boat",
"total": 5
},
{
"SectionSize": 10,
"name": "Small Boat",
"total": 10
},
{
"SectionSize": 15,
"name": "Large Boat",
"total": 15
}
]
}
Related
I have a lot of data I need to parse though.
I need to pull all pid's and price's.
`
[
{
"id": 159817,
"price": "10.69",
"stocked": true,
"store": {
"id": 809,
"nsn": "22036-0",
"pricingSource": "manual",
"lastUpdated": "2022-12-05T15:24:33.908Z"
},
"sharedFields": {
"type": "PRODUCT",
"id": 24549,
"pid": "12079",
"labels": [
{
"type": "default",
"value": "Chicken Sandwich",
"locale": "en"
},
{
"type": "fresh",
"value": "Chicken",
"locale": "en"
},
{
"type": "product_json",
"value": "Chicken",
"locale": "en"
}
],
"calMin": 600,
"calMax": 600,
"lastUpdated": "2021-12-31T13:49:22.794Z"
}
},
{
"id": 159818,
"price": "9.29",
"stocked": true,
"store": {
"id": 809,
"nsn": "22036-0",
"pricingSource": "manual",
"lastUpdated": "2022-12-05T15:24:33.908Z"
},
"sharedFields": {
"type": "PRODUCT",
"id": 25,
"pid": "1",
"labels": [
{
"type": "default",
"value": "Ham Sandwich",
"locale": "en"
},
{
"type": "fresh",
"value": "Ham",
"locale": "en"
}
],
"calMin": 540,
"calMax": 540,
"lastUpdated": "2021-07-09T19:30:00.326Z"
}
}
]
`
and I need to place them into a string like this, but on a scale of 150 products. I'd also need to change "pid" to "productId"
[{ "productId": "46238", "price": 6.09 }, { "productId": "40240", "price": 1.49 }]
I need to add a string before this data, but I'm pretty confident I can figure that part out.
I am pretty open to the easiest suggestion, whether that be VBS, Excel macro, etc.
I got a collection but I want to sort that collection. If the two application's cgpa is equal then sort the list collection according to the annual_salary where lower will up at list. Default the collection sort with the cgpa. below is my server response.
Thanks in advance
"applications": [
{
"id": 1,
"name": "Dr. W Khan",
"annual_salary": 5000,
"created_at": "2022-11-07T19:16:01.000000Z",
"updated_at": "2022-11-07T19:16:01.000000Z",
"education": [
{
"id": 1,
"application_id": 1,
"name": "HSC",
"cgpa": 400,
"created_at": "2022-11-07T19:16:01.000000Z",
"updated_at": "2022-11-07T19:16:01.000000Z"
}
]
},
{
"id": 2,
"name": "Dr. M Khan",
"annual_salary": 7000,
"created_at": "2022-11-07T19:16:14.000000Z",
"updated_at": "2022-11-07T19:16:14.000000Z",
"education": [
{
"id": 2,
"application_id": 2,
"name": "HSC",
"cgpa": 350,
"created_at": "2022-11-07T19:16:14.000000Z",
"updated_at": "2022-11-07T19:16:14.000000Z"
}
]
},
{
"id": 3,
"name": "Dr.",
"annual_salary": 5000,
"created_at": "2022-11-07T19:16:28.000000Z",
"updated_at": "2022-11-07T19:16:28.000000Z",
"education": [
{
"id": 3,
"application_id": 3,
"name": "HSC",
"cgpa": 350,
"created_at": "2022-11-07T19:16:28.000000Z",
"updated_at": "2022-11-07T19:16:28.000000Z"
}
]
}
]
This is the query for me.
$application = Application::with(
[
'education' => function ($query) {
$query->orderBy('cgpa', 'desc');
},
]
)
->orderBy('annual_salary', 'asc')
->get();
But ordering the list followed by a second orderBy.
I am trying to transform my JSON to different structure using JQ. I am able to achieve my new structure, however i am getting feilds with Null objects if they are not present in Source, my client wants to remove the fields if they are having null values..
As i iterate i am able to get the structure in new format. But additional structures are coming.
Code Snippet- https://jqplay.org/s/w2N_Ozg9Ag
JSON
{
"amazon": {
"activeitem": 2,
"createdDate": "2019-01-15T17:36:31.588Z",
"lastModifiedDate": "2019-01-15T17:36:31.588Z",
"user": "net",
"userType": "new",
"items": [
{
"id": 1,
"name": "harry potter",
"state": "sold",
"type": {
"branded": false,
"description": "artwork",
"contentLevel": "season"
}
},
{
"id": 2,
"name": "adidas shoes",
"state": null ,
"type": {
"branded": false,
"description": "Spprts",
"contentLevel": "season"
}
},
{
"id": 3,
"name": "watch",
"type": {
"branded": false,
"description": "walking",
"contentLevel": "special"
}
},
{
"id": 4,
"name": "adidas shoes",
"state": "in inventory",
"type": {
"branded": false,
"description": "running",
"contentLevel": "winter"
}
}
],
"product": {
"id": 4,
"name": "adidas shoes",
"source": "dealer",
"destination": "resident"
}
}
}
JQ Query:
.amazon | { userType: .userType, userName: .user, itemCatalog: (.items | map({ itemId: .id, name, state} )) }
Expected Response:
{
"userType": "new",
"userName": "net",
"itemCatalog": [
{
"itemId": 1,
"name": "harry potter",
"state": "sold"
},
{
"itemId": 2,
"name": "adidas shoes"
},
{
"itemId": 3,
"name": "watch"
},
{
"itemId": 4,
"name": "adidas shoes",
"state": "in inventory"
}
]
}
With the query i have, i am getting state : null for the entries which has empty or null values. I want to hide the field itself in these cases.
Horrible solution, delete them after the query. There must be a neater way? (I started using jq today)
.amazon | { userType: .userType, userName: .user, itemCatalog: (.items | map({ itemId: .id, name, state} )) }| del(.itemCatalog[].state |select(. == null))
https://jqplay.org/s/jlNYmJNi25
I am trying to convert the following dataset:
var data = {
"csrf": "token",
"items": [
{"category": "product1", "image": "image1.jpg", "cost": "$6", "item_totals": [
{"category": "discount", "amount": "-$1.0"}]
},
{"category": "product2", "image": "image2.jpg", "cost": "$8", "item_totals": [
{"category": "discount", "amount": "-$1.2"}]
}],
"totals": [
{"category": "shipping", "amount": "$0.00", "name": "Shipping", "is_zero": true},
{"category": "taxes", "amount": "$0.00", "name": "Taxes", "is_zero": true}
],
"total": "$1234", "subtotal": "$1234", "id": abc123, "currency_code": "USD"}
into a single value, being the sum of all 'amount' values in the item_totals array(s). I cannot seem to do this whilst accounting a varying amount of records in 'items' & for empty 'item_total' arrays. Any help would be great!
var data = {
"csrf": "token",
"items": [{
"category": "product1",
"image": "image1.jpg",
"cost": "$6",
"item_totals": [{
"category": "discount",
"amount": "-$1.0"
}]
},
{
"category": "product2",
"image": "image2.jpg",
"cost": "$8",
"item_totals": [ // multiple item_totals
{
"category": "discount",
"amount": "-$1.2"
},
{
"category": "discount",
"amount": "-$1.2"
}
]
},
{
"category": "product2",
"image": "image2.jpg",
"cost": "$8",
"item_totals": [] // empty item_totals
},
{
"category": "product2",
"image": "image2.jpg",
"cost": "$8"
// absent item_totals
}
],
"totals": [{
"category": "shipping",
"amount": "$0.00",
"name": "Shipping",
"is_zero": true
},
{
"category": "taxes",
"amount": "$0.00",
"name": "Taxes",
"is_zero": true
}
],
"total": "$1234",
"subtotal": "$1234",
"id": "abc123",
"currency_code": "USD"
}
var totalAmount = _.chain(data.items)
.map(item => item.item_totals || []) // emit totals
.tap(console.log)
.reduce((memo, bucket) => memo.concat(bucket), []) // collect (flatten)
.tap(console.log)
.map(total => parseFloat(total.amount.replace('$', ''), 10)) // emit amounts
.tap(console.log)
.reduce((ret, amount) => ret + amount, 0) // collect (sum)
.value();
console.log(totalAmount);
<script src="http://underscorejs.org/underscore.js"></script>
I have below json
1)
"Cronresult|12":{
"_type": "DailyCampaignUsage",
"bids": [
{
"clicks": 3,
}
],
"campaignId": 2614,
}
2).a
"campaign|2614"{
"country": 14,
"_id": 2614,
}
2).b
"campaign|31"{
"country": 12,
"_id": 31,
}
I am trying below query
SELECT Campaign.country,count(DISTINCT Campaign._id) campaigns,
SUM(ARRAY_SUM(DailyCampaignUsage.`statistics`[*].clicks)) clicks,
FROM Inheritx DailyCampaignUsage
JOIN Inheritx Campaign ON KEYS ('Campaign|'||TOSTRING(DailyCampaignUsage.campaignId))
where DailyCampaignUsage._type='DailyCampaignUsage'
it is bring below result
{
"country": "14",
"campaigns": 2614,
"clicks":3
}
BUT
I need output like below
{
"country": "12",
"campaigns": 31,
"clicks":0
},
{
"country": "14",
"campaigns": 2614,
"clicks":3
},
I need to here RIGHT JOIN like MySQL.
Can I do it here in N1QL ??
if Yes then how can I do it ??