Vega-Lite - How to calculate the difference of values from different rows in my data? - visualization

My current minimal example looks like:
{
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"data": {"values": [
{"year":2022, "week":1, "val":5},
{"year":2022, "week":2, "val":4},
{"year":2022, "week":3, "val":6},
{"year":2021, "week":1, "val":3},
{"year":2021, "week":2, "val":7}
]},
"mark":"line",
"encoding": {
"x":{"field":"week"},
"y":{"field":"val"},
"color":{"field":"year"}
}
}
I would like to calculate the difference of the week's values for this year and the previous year (if one of the values is missing, the difference should not be displayed). So for week 1 I would like to get a difference of 2 (=5 - 3) and for week 2 I would like to get a difference of -3 (= 4 - 7).
It seems like a common thing to do, but I found no examples or documentation solving this problem. I managed to produce the desired output with a kind of very ugly LAG transform but this does only work, if there are the same number of weeks in both years which is not always the case.
Maybe, one could somehow transform the data, that the week's values of this and the previous year appear in the same column?

This works for me.
{
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"data": {
"name": "myData",
"values": [
{"year": 2022, "week": 1, "val": 5},
{"year": 2022, "week": 2, "val": 4},
{"year": 2022, "week": 3, "val": 6},
{"year": 2021, "week": 1, "val": 3},
{"year": 2021, "week": 2, "val": 7}
]
},
"transform": [
{
"window": [{"op": "lead", "field": "val", "as": "lastVal"}],
"groupby": ["week"]
},
{
"calculate": "datum.lastVal==null?0: datum.val - datum.lastVal",
"as": "diff"
}
],
"mark": "line",
"encoding": {
"x": {"field": "week"},
"y": {"field": "val"},
"color": {"field": "year"}
}
}

Related

How can I compute the income of the sellerId of the products?

I'm trying to learn the advanced mongodb+mongoose function, so this is the result of my orders, and what I'm trying to do here is to compute the total amounts related to the sellerId
So in this one, I have two documents, the document 1 have an amount of 99 and and the other one is 11
so I need to get the sum of two. I've been searching and found the aggregate, but I can't figure out how I can combine the two documents.
[
{
"_id": "6360d1d0bd860240e2589564",
"userId": "6360cf687e186ebe29ab2a29",
"products": [
{
"productId": "6360cdd166480badb8c1e05b",
"quantity": 1,
"sellerId": "6360c6ed05e1e99034b5f7eb",
"_id": "6360d1d0bd860240e2589565"
}
],
"amount": 99,
"location": "asdsad",
"time": "asdsad",
"status": "pending",
"tax": 0.99,
},
{
"_id": "6360d7978044f3048e59bf34",
"userId": "6360d50dbd860240e258c585",
"products": [
{
"productId": "6360d7528044f3048e59bb6c",
"quantity": 1,
"sellerId": "6360d4d5bd860240e258c582",
"_id": "6360d7978044f3048e59bf35"
},
{
"productId": "6360d7868044f3048e59bd8c",
"quantity": 1,
"sellerId": "6360d4d5bd860240e258c582",
"_id": "6360d7978044f3048e59bf36"
}
],
"amount": 11,
"location": "Gym",
"time": "8:00 AM",
"status": "pending",
"tax": 0.11,
}
]
This might helps.
db.collection.aggregate([
{
$group: {
_id: null,
count: {
$sum: "$amount"
}
}
}
])

Sum value of elements and update field Mongo db

How Can I sum price on array "Elemets" and set on Document field Value?
I know how to do It in sql but I,m beginner in mongo.
{
"Document": [
{
"Id": 1,
"Type": "FV",
"Number": 34521,
"Year": 2020,
"Date": "2020-01-01T00:00:00",
"Value": 27.68,
"Elements": [
{
"Id": 1,
"DocumentId": 1,
"ProductId": 1,
"Quantity": 5.00,
"Price": 17.50,
"Task": 0.23
},
{
"Id": 2,
"DocumentId": 1,
"ProductId": 2,
"Quantity": 3.00,
"Price": 24.50,
"Task": 0.23
},
]
},
If you are using MongoDB 4.2, you can use $reduce to calculate the sum in the pipeline form of update.

What is the solution to "Too many positional (i.e. '$') elements found in path"?

I have searched over the web for this issue, the conclusion where I have reached is that it is a bug in the latest version of mongo as told here and here
The problem is that the structure of the object is as following:
{
"_id": 2,
"status": 0,
"details": [{
"id": 2,
"category": "A",
"obj": {
"apple": 5,
"banana": 2,
"cherry": 10
},
"members": [{
"id": 3,
"category": "A",
"obj": {
"apple": 5,
"banana": 2,
"cherry": 10
}
},
{
"id": 4,
"category": "A",
"obj": {
"apple": 5,
"banana": 2,
"cherry": 10
}
}
]
}]
}
which I am using everywhere in my project which is almost ready. But now the requirement is to update the obj inside the members object. For which I tried
cond := bson.M{ "$and": []bson.M{ bson.M{"details":bson.M{ "$elemMatch": bson.M{ "category": "A"} } }, bson.M{"status":0} } }
query := bson.M{ "$set": bson.M{ "details.$.members.$.obj.guava":15 } }
_, err := models.DbUpdateAll(Collection, cond, query)
But it is not working. Do I need to change the whole structure of the document by maintaining the array in different collection and passing reference to this object? It will be really a bad idea as for now where the project stands.... Isn't there any easy solution?

MongoDb get last and max values with timestamps

I am new to MongoDb as I only installed it yesterday...
I have a collection of temperature readings from n rooms:
[
{
"key": "livingRoom",
"name": "Living Room",
"temp": 19.437,
"ts": "2017-04-29T07:20:22.000Z"
},
{
"key": "bedroom",
"name": "Bedroom",
"temp": 24.875,
"ts": "2017-04-29T07:21:14.000Z"
}
]
and I want to get the current (last) temperature and the min/max over the last 24 hours for each room. I also want the timestamp of the min and max values.
I am 90% of the way there but as always that last 10% seems to take 90% of the time.
I have this aggregation:
{
"$group": {
"_id": "$key",
"temp": {"$last": "$temp"},
"name": {"$last": "$name"},
"ts": {"$last": "$ts"},
"maxTemp": {"$max": "$temp"},
"minTemp": {"$min": "$temp"}
}
}
That produces this result:
[
{
"_id": "bedroom",
"temp": 22.25,
"name": "Bedroom",
"ts": "2017-04-30T07:31:30.000Z",
"maxTemp": 24.875,
"minTemp": 21.437
},
{
"_id": "livingRoom",
"temp": 18.75,
"name": "Living Room",
"ts": "2017-04-30T07:39:38.000Z",
"maxTemp": 19.625,
"minTemp": 17.625
}
]
but of course that doesn't include the timestamp of the min and max values.
This question:
Multiple group operations using Mongo aggregation framework was useful and seems to indicate that I can't do what I want to.
I was planning on using different groups with different sorts to get the different aggregations that I want but as a group acts on the result of the last group it seems that what I am trying to do can't be done by mongo.

mongodb: delete object within an array, nested within two objects

I am trying to delete an object within an array. But that array is nested within two objects. How do I do this?
For example: let's say I want to delete the transaction with
_id: 58c3154a19f82c0ddc53f0de
How would I do this??
{
"_id": {
"$oid": "58bad6cf93ab9703da331e25"
},
"username": "david.lam#transfast.com",
"password": "sha1$fc05ad7d$1$1cc86a287642516f947fda520ae8ddd42e983e23",
"firstName": "David",
"lastName": "David",
"transactions": {
"2017": {
"3": [
{
"where": "Duane Reade",
"what": "asdf",
"category": 6,
"amount": "34",
"_id": {
"$oid": "58c300ef1602f90c7166cbfb"
},
"date": {
"day": 10,
"month": 3,
"year": 2017
}
},
{
"where": "Amazon",
"what": "asdf",
"category": 2,
"amount": "100",
"_id": {
"$oid": "58c3154a19f82c0ddc53f0de"
},
"date": {
"day": 10,
"month": 3,
"year": 2017
}
}
]
}
}
}
To do so you need to use the $pull operator. Address array elements with the dot notation. The following query does the job:
db.user1.update({},
{$pull: {'transactions.2017.3': {_id: ObjectId("58c3154a19f82c0ddc53f0de")}}
});