Setting the file. One moment.
DEPLOY IRQL FUNCTIONS · Azure Kusto Irql Graph · microsoft/azure-skills · Skills Docs
The Lift_To_Graph, Graph_Render_View, and Graph_Fold_By_Property functions must be present in the target Kusto database. They are pre-deployed on the kc7001 example cluster but may be missing on other clusters.
ContentsBack to the top of the page If any required function is missing, deploy it using the .create-or-alter commands below.
Run each .create-or-alter block above in Kusto Explorer or the ADX web UI against your target database. The functions are placed in the irql_draft folder.
After deployment, verify:
references/DEPLOY_IRQL_FUNCTIONS.md
(mapping_json)
};
let Tpacked = (T:()) {
T | extend _row = pack_all ()
};
let KustoResultsToNodes = (T:(), mapping_json: dynamic ) {
let NodeExpanded =
Tpacked(T)
| mv-expand nodeDef = mapping(mapping_json).node_types to typeof( dynamic )
| extend name= tostring (_row[ tostring (nodeDef.key)]),
type= tostring (nodeDef.type),
_nodeKeys= iif ( isnull (nodeDef.props), dynamic ([]),nodeDef.props),
defaults=nodeDef.defaults
| extend nodeColor= iff ( isnotnull (nodeDef.color), tostring (_row[ tostring (nodeDef.color)]), "" )
| extend nodeSize= iff ( isnotnull (nodeDef.size), toreal (_row[ tostring (nodeDef.size)]), 1.0 )
| extend iconColor= iff ( isnotnull (nodeDef.iconColor), tostring (_row[ tostring (nodeDef.iconColor)]), "" )
| extend id = strcat (nodeDef.id, "/" ,name)
| extend nodeDisplayName= iff ( isnotnull (nodeDef.displayName),
strcat (type, '/' , tostring (_row[ tostring (nodeDef.displayName)])), id)
| extend defIcon = iif ( isnotempty (nodeDef.defIcon), nodeDef.defIcon, "" )
| where isnotempty ( split (id, "/" )[- 1 ])
| extend type = tostring (nodeDef.type)
| extend iconUrl= ""
| invoke calcIcon ();
let NodePropsFilled = (T:(_row: dynamic , _nodeKeys: dynamic , id: string , type: string ,
nodeDisplayName: string , nodeColor: string , nodeSize: real ,
iconUrl: string , iconColor: string , defaults: dynamic )) {
T
| mv-expand k=_nodeKeys to typeof( string )
| extend v=_row[k], def=defaults[k]
| extend v = iif ( isnull (v) or isempty ( tostring (v)), iif ( isnull (def), v, def), v)
| summarize properties= make_bag ( bag_pack (k,v))
by id,type,nodeDisplayName,nodeColor,nodeSize,iconUrl,iconColor
};
let NodeNoProps = (T:(_nodeKeys: dynamic , id: string , type: string ,
nodeDisplayName: string , nodeColor: string , nodeSize: real ,
iconUrl: string , iconColor: string )) {
T
| where array_length (_nodeKeys)== 0
| extend properties= dynamic ( {} )
| project id,type,properties,nodeDisplayName,nodeColor,nodeSize,iconUrl, iconColor
};
let Nodes = (T:(_row: dynamic , _nodeKeys: dynamic , id: string , type: string ,
nodeDisplayName: string , nodeColor: string , nodeSize: real ,
iconUrl: string , iconColor: string , defaults: dynamic ))
{
union
NodePropsFilled(T),
NodeNoProps(T)
| project id,type,properties,nodeDisplayName,nodeColor,nodeSize,iconUrl, iconColor
};
union
(T | extend EntityType = "data" ),
(Nodes(NodeExpanded) | extend EntityType = "node" )
};
let KustoResultsToEdges = (T:(EntityType: string , ),mapping_json: dynamic ) {
let edges = datatable (SourceId: string , TargetId: string ) [];
let EdgeExpanded =
Tpacked((T | where EntityType == "data" ))
| extend nodeDef = mapping(mapping_json).node_types
| mv-expand edgeDef = mapping(mapping_json).edges to typeof( dynamic )
| mv-apply nodeDefSrc = nodeDef on (
where tostring (nodeDefSrc[ "type" ]) == tostring (edgeDef.source.type))
| extend SourceId = strcat (nodeDefSrc.id, "/" , tostring (_row[ tostring (nodeDefSrc.key)]))
| mv-apply nodeDefTgt = nodeDef on (
where tostring (nodeDefTgt[ "type" ]) == tostring (edgeDef.target.type))
| extend TargetId = strcat (nodeDefTgt.id, "/" , tostring (_row[ tostring (nodeDefTgt.key)]))
| extend edgeType= tostring (edgeDef.type),
_edgeKeys= iif ( isnull (edgeDef.props), dynamic ([]),edgeDef.props)
| extend edgeDisplayName = iff ( isnotnull (edgeDef.displayName),
strcat (edgeType, '/' , tostring (_row[ tostring (edgeDef.displayName)])), edgeType)
| extend edgeColor= iff ( isnotnull (edgeDef.color),
tostring (_row[ tostring (edgeDef.color)]), edgeType);
let EdgePropsFilled = (T:(_row: dynamic , _edgeKeys: dynamic ,
SourceId: string , TargetId: string , edgeType: string ,
edgeDisplayName: string , edgeColor: string )) {
T
| mv-expand k=_edgeKeys to typeof( string )
| extend v=_row[k]
| summarize edgeProperties= make_bag ( bag_pack (k,v))
by SourceId,TargetId,edgeType,edgeDisplayName,edgeColor
};
let EdgeNoProps = (T:(_edgeKeys: dynamic , SourceId: string , TargetId: string ,
edgeType: string , edgeDisplayName: string , edgeColor: string )) {
T
| where array_length (_edgeKeys)== 0
| extend edgeProperties= dynamic ( {} )
| project SourceId,TargetId,edgeType, edgeProperties,edgeDisplayName,edgeColor
};
let Edges = (T:(_edgeKeys: dynamic , SourceId: string , TargetId: string ,
edgeType: string , edgeDisplayName: string , edgeColor: string )) {
union
EdgePropsFilled(EdgeExpanded),
EdgeNoProps(EdgeExpanded)
| where isnotempty ( split (SourceId, "/" )[- 1 ]) and isnotempty ( split (TargetId, "/" )[- 1 ])
| project-reorder SourceId,TargetId,edgeType,edgeProperties,edgeDisplayName,edgeColor
};
union
(T | where EntityType== "node" ),
(Edges(EdgeExpanded) | extend EntityType = "edge" )
};
T
| invoke KustoResultsToNodes (mappingJson)
| invoke KustoResultsToEdges (mappingJson)
| where EntityType != "data"
| project EntityType, id, type, properties, nodeDisplayName, nodeColor, nodeSize,
iconUrl, iconColor, SourceId, TargetId, edgeType, edgeProperties,
edgeDisplayName, edgeColor
}
, edgeProperties:
dynamic
,
edgeDisplayName: string , edgeColor: string ), NodeType: string , PropertyName: string )
{
let Nodes =
T
| where EntityType == "node"
| project EntityType, id, type, properties, nodeDisplayName, nodeColor, nodeSize, iconUrl, iconColor,
SourceId= "" , TargetId= "" , edgeType= "" , edgeProperties= dynamic ( null ),
edgeDisplayName= "" , edgeColor= "" ;
let Edges =
T
| where EntityType == "edge"
| project EntityType, id= "" , type= "" , properties= dynamic ( {} ),
nodeDisplayName= "" , nodeColor= "" , nodeSize= real ( 0 ), iconUrl= "" , iconColor= "" ,
SourceId, TargetId, edgeType, edgeProperties, edgeDisplayName, edgeColor;
let FoldedNodes =
Nodes
| where type == NodeType
| where isnotempty (properties[PropertyName])
| extend val = tostring (properties[PropertyName])
| summarize members = make_list (id), memberCount = count() by val
| where memberCount > 1
| extend
id = strcat (PropertyName, "/" , val),
type = PropertyName,
EntityType = "node" ,
properties = pack ( "folded" , val,
"memberCount" , memberCount,
"members" , members),
nodeDisplayName = strcat (PropertyName, "/" , val),
nodeColor = "" , nodeSize = real ( 0 ),
iconUrl = "" , iconColor = ""
| project EntityType, id, type, properties, nodeDisplayName, nodeColor, nodeSize, iconUrl, iconColor,
SourceId= "" , TargetId= "" , edgeType= "" , edgeProperties= dynamic ( null ),
edgeDisplayName= "" , edgeColor= "" ;
let MemberToFold =
Nodes
| where type == NodeType
| where isnotempty (properties[PropertyName])
| extend val = tostring (properties[PropertyName])
| join kind = inner (
FoldedNodes
| extend val = tostring (properties[ "folded" ])
| project val, foldId=id
) on val
| project memberId=id, foldId;
let RewiredEdges =
Edges
| lookup kind = leftouter (MemberToFold | project SourceId=memberId, FoldSourceId=foldId) on SourceId
| lookup kind = leftouter (MemberToFold | project TargetId=memberId, FoldTargetId=foldId) on TargetId
| extend
NewSourceId = coalesce (FoldSourceId, SourceId),
NewTargetId = coalesce (FoldTargetId, TargetId)
| where NewSourceId != NewTargetId
| project EntityType= "edge" ,
id= "" , type= "" , properties= dynamic ( {} ),
nodeDisplayName= "" , nodeColor= "" , nodeSize= real ( 0 ), iconUrl= "" , iconColor= "" ,
SourceId=NewSourceId, TargetId=NewTargetId, edgeType, edgeProperties,
edgeDisplayName, edgeColor;
let FoldedMemberIds = MemberToFold | distinct memberId;
union
(Nodes | where id !in (FoldedMemberIds)),
FoldedNodes,
RewiredEdges
}