Creating tiles in azure sentinel workbook using KQL - kql

I am using this query to display what I want in workbook, but I want to have individual tiles with their values respectively for very high, high, medium, etc. But when I write this query and turn on tiles in visualization, it wont give me options to create tile for each of the variable in tile settings. What can I do to achieve this?
InALogs_CL
| summarize VeryHigh=count(risk_level_s=="very-high" or risk_assessment_risk_level_s=="very-high"), High=count(risk_level_s=="high" or risk_assessment_risk_level_s=="high"), Medium=count(risk_level_s=="medium" or risk_assessment_risk_level_s=="medium"), Low=count(risk_level_s=="low" or risk_assessment_risk_level_s=="low"), VeryLow=count(risk_level_s=="very-low" or risk_assessment_risk_level_s=="very-low"), None=count(risk_level_s=="none" or risk_assessment_risk_level_s=="none")

Each row result of the query will become a tile. so if you want tiles for each severity, you'd want to do something more like
| extend severity = case(
risk_level_s=="very-high" or risk_assessment_risk_level_s=="very-high". "Very High",
risk_level_s=="high" or risk_assessment_risk_level_s=="high","High",
risk_level_s=="medium" or risk_assessment_risk_level_s=="medium", "Medium",
risk_level_s=="low" or risk_assessment_risk_level_s=="low", "Low",
risk_level_s=="very-low" or risk_assessment_risk_level_s=="very-low", "Very Low"
risk_level_s=="none" or risk_assessment_risk_level_s=="none", "None",
"unknown")
| summarize count() by severity
which would end up with a result like
severity
count_
Very High
1
Low
1
unknown
27
you could then use the "Thresholds" renderer in the tiles to assign specific icons to the severities as the title field of the tiles, and use the "Big Number" renderer in the left section of the tile.
you'd have no tiles for the severities that don't have any matching rows.
If you need all the tiles, even 0's, you could either anti-join with a datatable that has the individual rows with 0's, or you could keep something like your original query (though i think the count items you have above should be countif ?), and add a | evaluate narrow() to the end.
Not all data sources support the evaluate operator though (like Azure Resource Graph queries do not).
you might also want to use =~ in all those comparisons if there's any chance that the values could be in other cases, right now, you'd get "unknown" of the risk level value was "High" or "HIGH", as this is only looking for all lower case "high"

I got the answer, I had to use datatable for those values to get converted into a separate table so that every severity category can be detected in tiles settings.
datatable (Count: long, status: string) [0, "Very High", 0, "High", 0, "Medium", 0, "Low", 0, "Very Low", 0, "None"]
| union
(
InALogs_CL
| extend status = case(
risk_level_s == "very-high" or risk_assessment_risk_level_s
== "very-high", "Very High",
risk_level_s == "high" or risk_assessment_risk_level_s
== "high", "High",
risk_level_s == "medium" or risk_assessment_risk_level_s
== "medium", "Medium",
risk_level_s == "low" or risk_assessment_risk_level_s
== "low", "Low",
risk_level_s == "very-low" or risk_assessment_risk_level_s
== "very-low", "Very Low",
risk_level_s == "none" or risk_assessment_risk_level_s
== "none", "None",
"True"
)
| where status != "True"
| summarize Count = count() by status
)
| summarize Count=sum(Count) by status

Related

MongoDB - how to get last item within a two level hierarchy

My goal is to get the last stock quote from a database for each of the ticker symbols in the list.
I found the $last function, but not sure how to apply it to a level of a hierarchy, i.e. the per ticker symbol. (I just realized I only have need one level in the hierarchy now, but it would be nice to know how to do it for two als0. Per this doc page, the _id is supposed to be the group by expression, and I have set that to the ticker symbol.
(I'm using Python3 and PyMongo.)
This is the query I have now, but it is only returning one row. I want it to return 4 rows, one for each ticker.
tickerList = ['AAPL', 'MSFT', 'AMZN', 'NFLX']
docs = dbCollectionQuotes.aggregate([
{'$match': {
'$and': [
{'timestampYear': 2020},
{'timestampMonth': 10},
{'timestampDay': 6},
{'timestampHour': 15},
{'ticker': {'$in': tickerList }}
]
}},
{'$sort': {
'ticker': 1,
'timestampIsoDateTime': 1
}},
{'$group': {
'_id': '$ticker',
'lastId': {'$last': '$_id'},
'minuteClose': {'$last': '$minuteClose'},
'todaysChangePerc': {'$last': '$todaysChangePerc'},
'timestampIsoDateTime': {'$last': '$timestampIsoDateTime'}
}}
])

Filter Payload with Dataweave for a Set Variable component

For the Mulesoft 4.2 Set Variable component, I want to assign a simple String value pulled from a single specific record from an incoming JSON payload.
In my case, taking just the value from the 'country' field from below example:
[
{
"salesID": "4404Bob Builder210032011-02-18T15:52:21+0.00",
"id": "4404",
"firstName": "Bob",
"lastName": "Builder",
"address": "181 Construction Road, Adelaide, NSW",
"postal": "21003",
"country": "New Zealand",
"creationDate": "2011-02-18T15:52:21+0.00",
"accountType": "personal",
"miles": 17469
}
]
A non-dynamic way to do this is like:
payload[0].country
I believe the best way to do this is with the filter function. The below option gives me the entire object, but I just want the country field.
payload filter ($.id == "4404")
Map function seems to be overkill for this since I only want the value, itself. I must be missing the syntax to get at the country field.
I did some more investigating, and this solution got me close enough to what I wanted:
https://stackoverflow.com/a/43488566/11995149
For my code example using filter, I had to surround the whole expression in parenthesis, and then I can access the field with a dot reference,
but below code gives String value as a single record within an array:
(payload filter ($.id == "4404")).country
[
"New Zealand"
]
In my case, I know that just one result will be returned from the filtered payload, so I could get just the String value with:
(payload filter ($.id == "4404"))[0].country
enter image description here
Can you try any of below options:
1) (payload groupBy ((item, index) -> item.id))["4404"][0].country
OR
2) (payload map ((item, index) -> if(item.id == "4404") item.country else ""))[0]
Thanks,
Ashish

Calculated properties for each element in array

I have a use case where my data store has an array of products, each with a price and quantity.
What I would like to do is calculate the 'total' for each product (price x quantity). I can do so by created a new computed property which re-calculates the entire array, appending a new property with the total.
The issue is, this requires recalculating every item in the array every time a single item changes.
I could use a component to calculate and display, but I also need to calculate a total (which is the sum of all computed prices on each product).
Is there a more efficient way to do this?
[
{
"Product ID": 1,
"Price": 10,
"Quantity": 5,
"Calculated Total": 50
},
{
"Product ID": 2,
"Price": 12,
"Quantity": 10,
"Calculated Total": 120
}
]
You can use a computed value to map through the original array and sum the values. e.g say the original array is named originalArray, do:
computed: {
computedTotal() {
let sum = 0
originalArray.map(item => sum += item["Calculated Total"])
return sum
}
}

mongoDB: aggregation which adds a field of counting field in the collection

I am new to MongoDb and have a query which I am struggling with..
I have a collection of reported users which looks like this:
{
"_id": 1,
"userId": 1,
"reason": "some reason",
"date": "2017-07-22"
}
I need a query which will add to each report the number of reports for that userId.
meaning if the collection has 3 records with userId=1. the query will return three records and each of them will also include a field
count=3 meaning the record above will now look like this:
{
"_id": 1
"userId": 1,
"reason": "some reason",
"date": "2017-07-22",
"count": 3
}
I tried using $project and $addFields aggregations but was not able to add a field which is a result of a query over the whole collection.
any ideas?
The answer provided by Veeram is correct, just that if you are running mongodb version less than 3.6, in the last stage of aggregate you might want to replace the $replaceRoot operator with a $project
aggregate([
{$group:{_id:"$userId", "data":{"$push":"$$ROOT"}, count:{$sum:1} } },
{"$unwind":"$data"},
{$project:{_id:"$data._id", userId:"$data.userId", reason:"$data.reason", date:"$data.date", count:1}}
])

RavenDB facet takes to long query time

I am new to ravendb and trying it out to see if it can do the job for the company i work for .
i updated a data of 10K records to the server .
each data looks like this :
{
"ModelID": 371300,
"Name": "6310I",
"Image": "0/7/4/9/28599470c",
"MinPrice": 200.0,
"MaxPrice": 400.0,
"StoreAmounts": 4,
"AuctionAmounts": 0,
"Popolarity": 16,
"ViewScore": 0.0,
"ReviewAmount": 4,
"ReviewScore": 40,
"Cat": "E-Cellphone",
"CatID": 1100,
"IsModel": true,
"ParamsList": [
{
"ModelID": 371300,
"Pid": 188396,
"IntVal": 188402,
"Param": "Nokia",
"Name": "Manufacturer",
"Unit": "",
"UnitDir": "left",
"PrOrder": 0,
"IsModelPage": true
},
{
"ModelID": 371305,
"Pid": 398331,
"IntVal": 1559552,
"Param": "1.6",
"Name": "Screen size",
"Unit": "inch",
"UnitDir": "left",
"PrOrder": 1,
"IsModelPage": false
},.....
where ParamsList is an array of all the attributes of a single product.
after building an index of :
from doc in docs.FastModels
from docParamsListItem in ((IEnumerable<dynamic>)doc.ParamsList).DefaultIfEmpty()
select new { Param = docParamsListItem.IntVal, Cat = doc.Cat }
and a facet of
var facetSetupDoc = new FacetSetup
{
Id = "facets/Params2Facets",
Facets = new List<Facet> { new Facet { Name = "Param" } }
};
and search like this
var facetResults = session.Query<FastModel>("ParamNewIndex")
.Where(x => x.Cat == "e-cellphone")
.ToFacets("facets/Params2Facets");
it takes more than a second to query and that is on only 10K of data . where our company has more than 1M products in DB.
am i doing something wrong ?
In order to generate facets, you have to check for each & every individual value of docParamsListItem.IntVal. If you have a lot of them, that can take some time.
In general, you shouldn't have a lot of facets, since that make no sense, it doesn't help the user.
For integers, you usually use ranges, instead of the actual values.
For example, price within a certain range.
You use just the field for things like manufacturer, or the MegaPixels count, where you have lot number or items (about a dozen or two)
You didn't mention which build you are using, but we made some major improvements there recently.