I have a query from which I want to get a few variables: street, house, locality, region, countryName
let orderDate = datetime('2022-02-10');
let orderId = '0A524A2F83CCB1A311EC827458D6C4F6';
raw_events
| where timestamp between (orderDate .. 1d)
| where messageType == 'OrderPlacedEvent'
| extend messageAsJSON=parse_json(message)
| where messageAsJSON.orderId == orderId
| extend street = messageAsJSON.address.street
| extend house = messageAsJSON.address.house
| extend locality = messageAsJSON.address.locality
| extend region = messageAsJSON.address.region
| extend countryName = messageAsJSON.address.countryName
Is there a better way of achieving that other than executing the same query a few times:
let orderDate = datetime('2022-02-10');
let orderId = '0A524A2F83CCB1A311EC827458D6C4F6';
let street = raw_events
| where timestamp between (orderDate .. 1d)
| where messageType == 'OrderPlacedEvent'
| extend messageAsJSON=parse_json(message)
| where messageAsJSON.orderId == orderId
| project street = messageAsJSON.address.street;
let house = raw_events
| where timestamp between (orderDate .. 1d)
| where messageType == 'OrderPlacedEvent'
| extend messageAsJSON=parse_json(message)
| where messageAsJSON.orderId == orderId
| project street = messageAsJSON.address.house;
print toscalar(street),toscalar(house);
UPDATE
Made it the following way
let addres2look4 = raw_events
| where timestamp between (orderDate .. 1d)
| where messageType == mType
| where message.orderId == orderId
| project address = message.address
| evaluate bag_unpack(address);
let countryName = toscalar(addres2look4 | project countryName);
let region = toscalar(addres2look4 | project region);
let locality = toscalar(addres2look4 | project locality);
let street = toscalar(addres2look4 | project street);
let house = toscalar(addres2look4 | project house);
Here's an efficient way to achieve this (note the use of the materialize() function):
let addres2look4 = materialize(
raw_events
| where timestamp between (orderDate .. 1d)
| where messageType == mType
| where message.orderId == orderId
| project address = message.address
| evaluate bag_unpack(address));
let countryName = toscalar(addres2look4 | project countryName);
let region = toscalar(addres2look4 | project region);
let locality = toscalar(addres2look4 | project locality);
let street = toscalar(addres2look4 | project street);
let house = toscalar(addres2look4 | project house);
The materialize() function caches the subquery's result during the time of query execution, so that the subsequent let statements will be much faster.
Related
I am trying to create an ifelse statement in KQL but I cannot find documentation about if its possible to do what I am trying.
Basically what I am trying to do to summarize ONLY if the conditions(EventResults=="Success") are met and do another summarize if they arent.
summarize SuccessCount=count(), SuccessUsers=makeset(User) by SrcDvcIpAddr, bin(TimeGenerated, timeframe)
ELSE
summarize FailCount=count(), SuccessUsers=makeset(User) by SrcDvcIpAddr, bin(TimeGenerated, timeframe)
I didnt really find any information about where and how I could use iff other than with the extend operator on the offical microsoft documentation page.
Is what I am trying to do possible?
// Sample data generation. Not Part of the solution.
let imAuthentication = materialize(range i from 1 to 500 step 1 | extend User = strcat("user_", tostring(toint(rand(10))+1)), SrcDvcIpAddr = tostring(dynamic(["1.1.1.1", "2.2.2.2", "3.3.3.3"])[toint(rand(2))]), EventResult = tostring(dynamic(["Success", "Failure"])[toint(rand(2))]), EventType ="Logon", EventProduct = "AAD", TimeGenerated = ago(12h * rand()));
// Solution starts here.
let sigin_threshold = 5;
let endtime = 12h;
let timeframe = 15m;
imAuthentication
|where TimeGenerated >= ago(endtime)
and EventProduct == "AAD"
and EventType =="Logon"
and EventResult in ("Success", "Failure")
and SrcDvcIpAddr != "-"
and isnotempty(User)
|summarize SuccessCount = countif(EventResult == "Success")
,FailCount = countif(EventResult == "Failure")
,SuccessUsers = make_set_if(User, EventResult == "Success")
,FailUsers = make_set_if(User, EventResult == "Failure")
by SrcDvcIpAddr
,bin(TimeGenerated, timeframe)
|where FailCount > sigin_threshold
SrcDvcIpAddr
TimeGenerated
SuccessCount
FailCount
SuccessUsers
FailUsers
2.2.2.2
2023-01-20T10:15:00Z
3
7
["user_3","user_2"]
["user_8","user_2","user_10","user_6","user_3","user_5"]
2.2.2.2
2023-01-20T11:00:00Z
4
6
["user_9","user_3","user_6"]
["user_8","user_7","user_2","user_4","user_9"]
1.1.1.1
2023-01-20T11:15:00Z
4
6
["user_10","user_7","user_4"]
["user_9","user_4","user_3"]
1.1.1.1
2023-01-20T11:45:00Z
3
6
["user_2","user_1","user_7"]
["user_2","user_1","user_9","user_4"]
2.2.2.2
2023-01-20T12:15:00Z
3
8
["user_4","user_5"]
["user_6","user_8","user_7","user_2","user_3","user_1","user_5"]
Fiddle
I have an Azure AlertRule what validates a query, where to tables are joining on a timestamp.
Is seems like Azure is changing the query, replacing the statement bin(..) with bin_at(..).
The Original query:
The query, opened after the alert triggered.
In my case this change is enough to alter the result of the query, becuase the extra added parameter (yellow arrow).
Is there any way around the issue?
EDIT:
as David pointed out in the comments -
This behaviour can be reproduced by running this kql as the query of an alart rule:
print bin(now(), 1h)
Original:
For completness, i've added the entier query here. I was not able to shorten it more that this. (sorry)
let frame_size = 1h;
let messages = datatable (timestamp: datetime )
[
datetime(2022-11-09T23:01:00Z),datetime(2022-11-09T23:02:00Z),datetime(2022-11-09T23:03:00Z),datetime(2022-11-09T23:04:00Z),
datetime(2022-11-09T22:01:00Z),datetime(2022-11-09T22:02:00Z),datetime(2022-11-09T22:03:00Z),datetime(2022-11-09T22:04:00Z),
datetime(2022-11-09T21:01:00Z),datetime(2022-11-09T21:02:00Z),datetime(2022-11-09T21:03:00Z),datetime(2022-11-09T21:04:00Z),
datetime(2022-11-09T20:01:00Z),datetime(2022-11-09T20:02:00Z),datetime(2022-11-09T20:03:00Z),datetime(2022-11-09T20:04:00Z),
datetime(2022-11-09T19:01:00Z),datetime(2022-11-09T19:02:00Z),datetime(2022-11-09T19:03:00Z),datetime(2022-11-09T19:04:00Z),
datetime(2022-11-09T18:01:00Z),datetime(2022-11-09T18:02:00Z),datetime(2022-11-09T18:03:00Z),datetime(2022-11-09T18:04:00Z),
datetime(2022-11-09T17:01:00Z),datetime(2022-11-09T17:02:00Z),datetime(2022-11-09T17:03:00Z),datetime(2022-11-09T17:04:00Z),
datetime(2022-11-09T16:01:00Z),datetime(2022-11-09T16:02:00Z),datetime(2022-11-09T16:03:00Z),datetime(2022-11-09T16:04:00Z),
datetime(2022-11-09T15:01:00Z),datetime(2022-11-09T15:02:00Z),datetime(2022-11-09T15:03:00Z),datetime(2022-11-09T15:04:00Z),
datetime(2022-11-09T14:01:00Z),datetime(2022-11-09T14:02:00Z),
datetime(2022-11-09T13:01:00Z),datetime(2022-11-09T13:02:00Z),
datetime(2022-11-09T12:01:00Z),datetime(2022-11-09T12:02:00Z),
datetime(2022-11-09T11:01:00Z),datetime(2022-11-09T11:02:00Z),
datetime(2022-11-09T10:01:00Z),datetime(2022-11-09T10:02:00Z),
datetime(2022-11-09T09:01:00Z),datetime(2022-11-09T09:02:00Z),
datetime(2022-11-09T08:01:00Z),datetime(2022-11-09T08:02:00Z),
datetime(2022-11-09T07:01:00Z),datetime(2022-11-09T07:02:00Z),
datetime(2022-11-09T06:01:00Z),datetime(2022-11-09T06:02:00Z),
datetime(2022-11-09T06:01:00Z),datetime(2022-11-09T06:02:00Z),
datetime(2022-11-09T05:01:00Z),datetime(2022-11-09T05:02:00Z),
datetime(2022-11-09T04:01:00Z),datetime(2022-11-09T04:02:00Z),
datetime(2022-11-09T03:01:00Z),datetime(2022-11-09T03:02:00Z),
datetime(2022-11-09T02:01:00Z),datetime(2022-11-09T02:02:00Z),
datetime(2022-11-09T01:01:00Z),datetime(2022-11-09T01:02:00Z),
datetime(2022-11-09T00:01:00Z),datetime(2022-11-09T00:02:00Z),
];
let create_time_intervals = (start_datetime: datetime, end_datetime: datetime, frame_size: timespan)
{
let hourly_distribution_as_dk_time = datatable (hour: int, expected_documents_count: int)
[0,2, 1,2, 2,2, 3,2, 4,2, 5,2, 6,2, 7,2, 8,2, 9,2, 10,2, 11,2, 12,2, 13,2, 14,2, 15,4, 16,4, 17,4, 18,4, 19,4, 20,4, 21,4, 22,4, 23,4 ]
;
let start_datetime_dk = datetime_utc_to_local(start_datetime, "Europe/Copenhagen");
let end_datetime_dk = datetime_utc_to_local(end_datetime, "Europe/Copenhagen");
// Generate all time frames for given interval excluding the first incomplete frame.
range frame_start from bin(start_datetime + frame_size, frame_size) to end_datetime step frame_size
| project bin(frame_start, frame_size)
| extend date_dk = datetime_utc_to_local(frame_start, "Europe/Copenhagen")
| extend hour = toint(datetime_part("Hour", date_dk))
| join kind=leftouter hourly_distribution_as_dk_time on hour
| project frame_start, expected_documents_count
| order by frame_start asc
};
let msg = messages
| where timestamp >= ago(1h)
|summarize cnt = count()
by frame_start = bin(timestamp,frame_size); // *** <==== this bin(..) changes when running ***
let frame_results = create_time_intervals(ago(1h), now(), frame_size)
| join kind=leftouter msg on frame_start
| extend ok = cnt;
frame_results
| summarize
sum_expected = sum(expected_documents_count),
sum_ok = sum(ok)
| extend ok = sum_expected == sum_ok
| extend ok_int = toint(ok) //for alerting purposes
Well, an obvious work-around would be to replace bin with bin_at, e.g. -
let timestamp = datetime(2000-03-04 11:22:33);
let frame_size = 1h;
print bin_at(timestamp, frame_size, datetime(2000))
print_0
2000-03-04T11:00:00Z
Fiddle
I'm using Pentaho(ETL) tool to achieve the output using a javascript component which accepts javascript code to achieve the desired transformation.The following table is imported into pentaho from a .csv file(source file).
For example this is my table structure
+--------+--------+--------+
| RLD | MD | INC |
+--------+--------+--------+
| 0 | 3868 | 302024 |
| 53454 | 7699 | 203719 |
| 154508 | 932 | 47694 |
| 107547 | 36168 | 83592 |
I want to use a script which would give me the max_value and its index number, such that my output would look like
Output Table
+--------+--------+--------+-----------+-----------+
| RQD | MT | IZC | max_value | max_index |
+--------+--------+--------+-----------+-----------+
| 0 | 3868 | 302024 | 302024 | 3 |
| 53454 | 7699 | 203719 | 203719 | 3 |
| 154508 | 932 | 47694 | 154508 | 1 |
| 456 | 107547| 83592 | 107547 | 2 |
To get the max value from rows I have used
var max_value = Math.max(RQD,MT,IZC);
println(max_value);
I tried to get their index using the following script
var max_index = switch (Math.max(RQD,MT,IZC))
{
case "RQD":document.write("1")
case "MT":document.write("2")
case "MT":document.write("3")
default:document.write("0")
}
How can I get the desired result in the form of javascript data structure? Any help would be much appreciated.Thanks
var list = [
{RLD:0,
MD:3868,
INC:302024
},
{RLD:53454,
MD:7699,
INC:203719
},
{RLD:154508,
MD:932,
INC:47694
},
{RLD:107547,
MD:36168,
INC:83592
},
];
list = list.map(function(item){
var keys = Object.keys(item);
item.max_value = item[keys[0]];
item.max_index = '';
for(var i = 1, l = keys.length; i < l; i++) {
var key = keys[i];
var keyValue = item[key];
if (item.max_value < keyValue){
item.max_value = keyValue;
item.max_index = key;
}
}
return item;
})
There are several issues with your code, lets solve them!
Use breaks: you must use breaks in order to avoid the switch moving to cases below its match.
switch cases do not return a value like functions, you cannot use a switch return to define a variable, you need to define the variable inside the switch case.
Math.max does not return the name of its maximum variable, instead it returns the maximum number from its given parameters.
to solve this issue, i would not use a switch case with math.max to be honest, however to answer your question:
var tableArray = [RQD,MT,IZC];
var maxIndex = tableArray.indexOf(Math.max.apply(null, arr));
if(maxIndex > -1) document.write(maxIndex+1);
i used +1 because you have your index in the example table starting from 1 instead of 0.
the way the array is sorted should match the way the table is sorted per raw.
First of all you could not solve this problem with a switch statement.
In a javascript switch you should provide a value that is one of the followed case(s), otherwise the switch will go to the default if defined.
Your problem seems to be to find out the higher value of 3 columns and print out, the colums row by row adding a column with the max value and the index of the column where you found it.
So for example on the row:
1, RLD : 0
2, MD : 3868
3, INC : 302024
In this case the higher value is INC with the column index 3.
If you have just the variables with the number values, you could do nothing more than something like this:
function getMaxValueRow (RLD, MD, INC) {
var max_value = RLD;
var max_index = 1;
if (MD > max_value) {
max_value = MD;
max_index = 2;
}
if (INC > max_value) {
max_value = INC;
max_index = 3;
}
return [RLD, MD, INC, max_value, max_index];
}
You could return an object too like this:
retrun {
'RQD': RLD,
'MT': MD,
'IZC': INC,
'max_value': max_value,
'max_index': max_index
}
I am getting the following error in my code:
org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; bad
SQL grammar [insert into bulletins (date, name, subject, note, approved) values
(?, ?, ?, ?, ?)]; nested exception is com.mysql.jdbc.exceptions.MySQLSyntaxError
Exception: Unknown column 'date' in 'field list'
This line is in my Spring controller.
bulletinDAO.writeBulletin(bulletin);
The actual place in my DAO class where I'm trying to write using Hibernate.
public void writeBulletin(Bulletin bulletin) {
try {
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
session.save(bulletin);
tx.commit();
} catch (Exception e) {
System.out.println(e.toString());
}
}
Here is my model class.
#Entity
#Table(name="login")
public class Bulletin {
#Id
#Column(name="id")
#GeneratedValue
private int id;
#Column(name="bulletin_date")
private String date;
#Column(name="name")
private String name;
#Column(name="subject")
private String subject;
#Column(name="note")
private String note;
#Column(name="approved")
private boolean approved;
// Getters and setters follow
}
Finally, here is the layout of the table.
+---------------+---------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+---------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| bulletin_date | varchar(10) | YES | | NULL | |
| name | varchar(30) | YES | | NULL | |
| subject | varchar(50) | YES | | NULL | |
| note | varchar(2500) | YES | | NULL | |
| approved | tinyint(1) | YES | | NULL | |
+---------------+---------------+------+-----+---------+----------------+
There must be something wrong with your getters and setters.
I would recommend changing the property name from date to bulletinDate. And then set & get it correctly...
#Column(name="bulletin_date")
private String bulletinDate;
public String getBulletinDate() {
return bulletinDate;
}
public void setBulletinDate(String bulletin_date) {
this.bulletinDate = bulletin_date;
}
Your issue is here
[insert into bulletins (date, name, subject, note, approved)]
Whereas you need bullletin_date.
From experience i needed to rebuild the project completely to ensure that right column name is referenced.
Clear your project cache and rebuild it.
Let me know how you go and i'll help further if it doesn't help.
Problem
I use hibernate to store data in an MySQL database. I now want to store a Company and one of its Branches.
The company:
#Entity
#Table(name="company")
public class Company {
#Id
#GeneratedValue
#Column(name="id")
private int id;
#Column(name="name")
private String name;
#ManyToMany(cascade = CascadeType.ALL)
#JoinTable(name="company_branch_join",
joinColumns={#JoinColumn(name="company_id")},
inverseJoinColumns={#JoinColumn(name="branch_id")})
private Set<CompanyBranch> branches;
// Getters and setters...
}
And the branch:
#Entity
#Table(name="company_branch")
public class CompanyBranch {
#Id
#GeneratedValue
#Column(name="id")
private int id;
#Column(name="branch")
private String branch;
#ManyToMany(mappedBy="branches", cascade = CascadeType.ALL)
private Set<Company> companies;
// Getters and setters...
}
Question
The code works and i can insert the data in the join table. The problem is the override policy regarding the branches. My branch table in the database is already filled with branches and its IDs so i don't want to modify the data. However on an company-insert the branches associated with the company get stored again and override the data with the same ID in the database. How can I prevent this behavior?
CompanyBranch cb1 = new CompanyBranch();
cb1.setId(1);
cb1.setBranch("Manufacturing");
CompanyBranch cb2 = new CompanyBranch();
cb2.setId(2);
cb2.setBranch("DONT-INSERT");
Company c = new Company();
c.setName("[Random-Company-Name]");
c.addBranch(cb1);
c.addBranch(cb2);
CompanyManager cm = new CompanyManagerImpl();
cm.saveCompany(c);
The branch table before execution looks like this:
| id | branch |
+----+----------------+
| 1 | Manufacturing |
| 2 | IT |
|... | ... |
The table should not change. But after execution it looks like this:
| id | branch |
+----+----------------+
| 1 | Manufacturing |
| 2 | DONT-INSERT |
|... | ... |
Instead of creating new branch instances with the new operator, retrieve a reference to them using EntityManager.getReference(), e.g.:
CompanyBranch cb1 = entityManager.getReference(CompanyBranch.class, 1);