Kusto extractjson not working with email address - azure-application-insights

I am attempting to use the extractjson() method that includes email addresses in the source data (specifically the # symbol).
let T = datatable(MyString:string)
[
'{"user#domain.com": {"value":10}, "userdomain.com": { "value": 5}}'
];
T
| project extractjson('$.["user#domain.com"].value', MyString)
This results in a null being returned, changing the JSONPath to '$.["userdomain.com"].value' does return the correct result.
Results
I know the # sign is a used as the current node in a filter expression, does this need to be escaped when used with KQL?
Just as a side note, I run the same test using nodes 'jsonpath' package and this worked as expected.
const jp = require('jsonpath');
const data = {"user#domain.com": {"value":10}, "name2": { "value": 5}};
console.log(jp.query(data, '$["user#domain.com"].score'));

you can use the parse_json() function instead, and when you don't have to use extract_json():
print MyString = '{"user#domain.com": {"value":10}, "userdomain.com": { "value": 5}}'
| project parse_json(MyString)["user#domain.com"].value
MyString_user#domain.com_value
10
From the documentation: https://learn.microsoft.com/en-us/azure/data-explorer/kusto/query/extractjsonfunction

Related

Extracting values with jq only when they exist

I have a large file of records that contain fields that look something like this:
{
"id": "1000001",
"updatedDate": "2018-12-21T01:52:00Z",
"createdDate": "1993-11-30T02:59:25Z",
"varFields": [
{
"fieldTag": "b",
"content": "1000679727"
},
{
"fieldTag": "v",
"content": "v.1"
}
}
I need to extract the .content element along with other things, but only when the fieldTag associated with it is "v". Only some records contain a fieldTag "v".
When I try to parse using
(.varFields[] |select(.fieldTag=="v") | "\(.content)") // ""
it works fine so long as v is present. However, when it is not present, I get
jq: error (at <stdin>:353953): Cannot iterate over null (null)
I tried to get rid of the error with multiple variations, including things to the effect of
(select((.varFields[] |select(.fieldTag=="v") | .content) != null) | .varFields[] |select(.fieldTag=="v") | "\(.content)") // ""
but I'm still getting the same error. What am I missing?
Take a look at the error suppression operator ? that works a bit like the new ?. nullable chaining operator in Javascript.
The ? operator, used as EXP?, is shorthand for try EXP.
Example:
jq '[.[]|(.a)?]'
Input [{}, true, {"a":1}]
Output [null, 1]
They have a slightly simpler demonstrable example of this at https://jqplay.org/jq?q=%5B.%5B%5D%7C(.a)%3F%5D&j=%5B%7B%7D%2C%20true%2C%20%7B%22a%22%3A1%7D%5D and the try-catch operator is similar if all you need is custom error handling (or just error ignoring...).

hasura_session invocation without arguments

There is a function:
CREATE OR REPLACE FUNCTION public.drops(cases_free_row cases_free, hasura_session json)
RETURNS SETOF drops
LANGUAGE sql
STABLE
AS $function$
SELECT *
FROM drops d
WHERE d.caseid = cases_free_row.id
AND d.userid = (hasura_session ->> 'x-hasura-user-id') :: INT
$function$
When I try to call, I need to enter the arguments
{
"errors": [
{
"extensions": {
"path": "$.selectionSet.cases_free.drops.args",
"code": "not-supported"
},
"message": "Non default arguments cannot be omitted"
}
]
}
Is it possible to get data without entering arguments?
Hasura v1.2.0-beta.3
You need the first args cases_free_row but for the second args hasura_session there, here's how to make it available to your function:
In Hasura Console go to Data, under Untracked Custom Functions, click track.
Your custom function will appear on left side panel, click to open
Then under Session argument insert hasura_session
Your specific postgres function requires arguments, so no.

Getting .key from Firebase using VueFire

I am trying to get a single key from firebase nodes and I can't get any from the code I have right now. Here is my code:
let app = Firebase.initializeApp(config)
let db = app.database()
let bdRef = db.ref()
export default {
name: 'hello',
firebase: {
businesses: bdRef.orderByChild('.key').equalTo('306')
}
}
I get this error when doing this:
validation.js?5c80:234 Uncaught Error: Query.orderByChild failed: First argument was an invalid path = ".key". Paths must be non-empty strings and can't contain ".", "#", "$", "[", or "]"`
When I do this with my code:
businesses: bdRef.orderByChild('title').equalTo('Feather Animation Wood Carving Supplies')
It comes with this array:
0:Object
.key:"3021"
address:"Hello Avenue"
city:""
description:"Wood carving tools and supplies. Please contact us by phone or internet."
email:"hi#gmail.com"
employees:"1"
How do I get the .key property?
Did you try use this command:
businesses['.key']
Its very simple answer that you have json with ".key" key and "3021" as its value. But in ".key" you have included "." which refers that you are giving empty path or maybe invalid path.
So if you name it as "key" or any name as "keyid" would be cool, unless you include as your error says can't contain ".", "#", "$", "[", or "]"
Hope this explanation helped!
As stated, you cannot query a property with a dot in its name. From the documentation, you need to use the built in orderByKey() filter instead:
export default {
name: 'hello',
firebase: {
businesses: bdRef.equalTo('306').orderByKey()
}
}

Groovy Map Issue with Variable Properties and String INterpolation

I have been navigating map structures fine for a long time now. Yet, for some reason, the root of this problem escapes me. I've tried bracket notation as well, no luck.
Why doesn't the final output (null) return "[serverinfo:[listenPort:19001]]"
If I replace the two instances of ' "$instanceName" ' with simply ' services ', it works.
String instanceName = "Services"
Map serverNode = [
instances:[
"$instanceName":[
serverinfo:[
listenPort:19001
]
]
]
]
println "$instanceName"
println serverNode.instances
println serverNode.instances."$instanceName"
//output
Services
[Services:[serverinfo:[listenPort:19001]]]
null
The type of "$instanceName" is GStringImpl, not String. It's a common mistake (and hard to find!)
def serverNode = [
instances:[
("$instanceName" as String):[
serverinfo:[
listenPort:19001
]
]
]
]
as stated by #tim_yates in comment, if your interpolated string is as simple as in this example (ie ,"${property}"), then you can use the (property) syntax : Groovy put the value of the property as a key, not the word "property"

One HTTP Delimiter to Rule Them All

I have a configuration file in the format of blah = foo. I would like to have entries like:
http = https://stackoverflow.com/questions,header keys and values,string to search for.
I'm okay requiring that the the url be urlecncoded. Is there any ASCII character I can use that won't be valid value anywhere in the above example (After splitting once on =)? My example uses a comma but I think that is valid in a header value?
After pouring through some RFCs I figure someone is more familiar with this can save me some pain.
Also my project is in Go if there are existing std library that might help with this...
You can use a non-ascii character and urlencode, for example using the middle dot (compose + ^ + . on linux):
const sep = `·`
const t = `http = https://stackoverflow.com/questions·string to search for·header=value·header=value`
func parseLine(line string) (name, url, search string, headers []string) {
idx := strings.Index(line, " = ")
if idx == -1 {
return
}
name = line[:idx]
parts := strings.Split(line[idx+3:], sep)
if len(parts) < 3 {
// handle invalid line
}
url, search = parts[0], parts[1]
headers = parts[2:]
return
}
Although, using JSON is probably the best and most long-term maintainable option.
For completeness sake, a json version would look like:
type Site struct {
Url string
Query string
Headers map[string]string
}
const t = `[
{
"url": "https://stackoverflow.com/questions",
"query": "string to search for",
"headers": {"header": "value", "header2": "value"}
},
{
"url": "https://google.com",
"query": "string to search for",
"headers": {"header": "value", "header2": "value"}
}
]`
func main() {
var sites []Site
err := json.Unmarshal([]byte(t), &sites)
fmt.Printf("%+v (%v)\n", sites, err)
}
Essentially you have to look at RFC 3986, RFC 7230 and friends to see what can occur.
URIs are simple if you insist on them to be valid, just use the space character or "<" and ">" as delimiters.
Field values can be almost anything; HTTP forbids control characters though, so you might be able to use horizontal TABs (if you're ok with getting into trouble with invalid field values).

Resources