Automate JSON substrings with semi-random data to KQL? - json

So currently I have the following simple code to just build out a table for myself and look at data
azure_devops_work_item_events_CL
| summarize any(WorkItemType_s, TeamProject_s, Title_s,
AssignedTo_s, State_s, Reason_s) by WorkItemId_d, Relations_s
| order by WorkItemId_d desc
My problem is the Relations_s data is pulling a super long string that's different in length pretty much every instance although the format is the same for each one ex:
Relations_s
[ { "rel": "System.LinkTypes.Hierarchy-Reverse", "url": "https://dev.azure.com/xxxx/a69ffa35-e99f-42ea-a254/_apis/wit/workItems/197138", "attributes": { "isLocked": false, "name": "Parent" } } ]
[ { "rel": "System.LinkTypes.Hierarchy-Reverse", "url": "https://dev.azure.com/xxxx/d88804f3-b064-4489-9705/_apis/wit/workItems/234449", "attributes": { "isLocked": false, "name": "Parent" } } ]
[ { "rel": "System.LinkTypes.Hierarchy-Forward", "url": "https://dev.azure.com/xxxx/a69ffa35-e99f-42ea-a254/_apis/wit/workItems/247970", "attributes": { "isLocked": false, "name": "Child" } }, { "rel": "System.LinkTypes.Hierarchy-Forward", "url": "https://dev.azure.com/xxxx/a69ffa35-e99f-42ea-a254/_apis/wit/workItems/242838", "attributes": { "isLocked": false, "name": "Child" } }, { "rel": "System.LinkTypes.Hierarchy-Forward", "url": "https://dev.azure.com/xxxx/a69ffa35-e99f-42ea-a254/_apis/wit/workItems/242835", "attributes": { "isLocked": false, "name": "Child" } }, { "rel": "System.LinkTypes.Hierarchy-Forward", "url": "https://dev.azure.com/xxxx/a69ffa35-e99f-42ea-a254/_apis/wit/workItems/246163", "attributes": { "isLocked": false, "name": "Child" } }, { "rel": "System.LinkTypes.Hierarchy-Forward", "url": "https://dev.azure.com/xxxx/a69ffa35-e99f-42ea-a254/_apis/wit/workItems/234839", "attributes": { "isLocked": false, "name": "Child" } }, { "rel": "System.LinkTypes.Hierarchy-Forward", "url": "https://dev.azure.com/xxxx/a69ffa35-e99f-42ea-a254/_apis/wit/workItems/229566", "attributes": { "isLocked": false, "name": "Child" } }, { "rel": "System.LinkTypes.Hierarchy-Forward", "url": "https://dev.azure.com/xxxx/a69ffa35-e99f-42ea-a254/_apis/wit/workItems/228347", "attributes": { "isLocked": false, "name": "Child" } }, { "rel": "System.LinkTypes.Hierarchy-Forward", "url": "https://dev.azure.com/xxxx/a69ffa35-e99f-42ea-a254/_apis/wit/workItems/240648", "attributes": { "isLocked": false, "name": "Child" } }, { "rel": "System.LinkTypes.Hierarchy-Forward", "url": "https://dev.azure.com/xxxx/a69ffa35-e99f-42ea-a254/_apis/wit/workItems/234833", "attributes": { "isLocked": false, "name": "Child" } }, { "rel": "System.LinkTypes.Hierarchy-Forward", "url": "https://dev.azure.com/xxxx/a69ffa35-e99f-42ea-a254/_apis/wit/workItems/240647", "attributes": { "isLocked": false, "name": "Child" } }, { "rel": "System.LinkTypes.Hierarchy-Forward", "url": "https://dev.azure.com/xxxx/a69ffa35-e99f-42ea-a254/_apis/wit/workItems/242837", "attributes": { "isLocked": false, "name": "Child" } }, { "rel": "System.LinkTypes.Hierarchy-Forward", "url": "https://dev.azure.com/xxxx/a69ffa35-e99f-42ea-a254/_apis/wit/workItems/234803", "attributes": { "isLocked": false, "name": "Child" } }, { "rel": "System.LinkTypes.Hierarchy-Forward", "url": "https://dev.azure.com/xxxx/a69ffa35-e99f-42ea-a254/_apis/wit/workItems/234801", "attributes": { "isLocked": false, "name": "Child" } }, { "rel": "System.LinkTypes.Hierarchy-Forward", "url": "https://dev.azure.com/xxxx/a69ffa35-e99f-42ea-a254/_apis/wit/workItems/246352", "attributes": { "isLocked": false, "name": "Child" } }, { "rel": "System.LinkTypes.Hierarchy-Forward", "url": "https://dev.azure.com/xxxx/a69ffa35-e99f-42ea-a254/_apis/wit/workItems/242839", "attributes": { "isLocked": false, "name": "Child" } }, { "rel": "System.LinkTypes.Hierarchy-Forward", "url": "https://dev.azure.com/xxxx/a69ffa35-e99f-42ea-a254/_apis/wit/workItems/234834", "attributes": { "isLocked": false, "name": "Child" } }, { "rel": "System.LinkTypes.Hierarchy-Forward", "url": "https://dev.azure.com/xxxx/a69ffa35-e99f-42ea-a254/_apis/wit/workItems/234838", "attributes": { "isLocked": false, "name": "Child" } }, { "rel": "System.LinkTypes.Hierarchy-Forward", "url": "https://dev.azure.com/xxxx/a69ffa35-e99f-42ea-a254/_apis/wit/workItems/242836", "attributes": { "isLocked": false, "name": "Child" } }, { "rel": "System.LinkTypes.Hierarchy-Reverse", "url": "https://dev.azure.com/xxxx/a69ffa35-e99f-42ea-a254/_apis/wit/workItems/218335", "attributes": { "isLocked": false, "name": "Parent" } }, { "rel": "System.LinkTypes.Hierarchy-Forward", "url": "https://dev.azure.com/xxxx/a69ffa35-e99f-42ea-a254/_apis/wit/workItems/234832", "attributes": { "isLocked": false, "name": "Child" } } ]
This is a small sample of what my table looks like when I query it. I'm completely lost on how I can parse the table in such a way that I'm able to automate pulling the number at the end of every link and the name portion at the end of each string. Especially when some parts of the table have 40 strings in 1. Note all the data is in the form of a JSON if that impacts this at all. The end result needs to look something like this
Child
Parent
240241
240541
Or this
Item
Link
240241
Child
240541
Parent
Apologies for the formatting I can't get the massive data set to properly format into a table

According to its name Relations_s is probably a string, therefore needs conversion to JSON (by using todynamic()).
Option 1
azure_devops_work_item_events_CL
| mv-apply todynamic(Relations_s) on
(
parse Relations_s.url with * "/" Item:long
| project Item
,Link = Relations_s.attributes.name
| summarize Parent = take_anyif (Item ,Link == "Parent")
,Children = make_list_if (Item ,Link == "Child")
)
Parent
Children
197138
[]
234449
[]
218335
[247970,242838,242835,246163,234839,229566,228347,240648,234833,240647,242837,234803,234801,246352,242839,234834,234838,242836,234832]
Option 2
azure_devops_work_item_events_CL
| mv-apply todynamic(Relations_s) on
(
parse Relations_s.url with * "/" Item:long
| project Item
,Link = Relations_s.attributes.name
| summarize Parent = take_anyif (Item ,Link == "Parent")
,Children = make_list_if (Item ,Link == "Child")
| mv-expand Children = iff(array_length(Children) == 0, dynamic(null), Children) to typeof(long)
)
Parent
Children
197138
234449
218335
247970
218335
242838
218335
242835
218335
246163
218335
234839
218335
229566
218335
228347
218335
240648
218335
234833
218335
240647
218335
242837
218335
234803
218335
234801
218335
246352
218335
242839
218335
234834
218335
234838
218335
242836
218335
234832

If I understood your description correctly, you could try the following, using the mv-apply and parse operators:
datatable(d:dynamic)
[
dynamic([
{
"rel": "System.LinkTypes.Hierarchy-Reverse",
"url": "https://dev.azure.com/xxxx/a69ffa35-e99f-42ea-a254/_apis/wit/workItems/197138",
"attributes": {
"isLocked": false,
"name": "Parent"
}
}
]), dynamic([
{
"rel": "System.LinkTypes.Hierarchy-Reverse",
"url": "https://dev.azure.com/xxxx/d88804f3-b064-4489-9705/_apis/wit/workItems/234449",
"attributes": {
"isLocked": false,
"name": "Parent"
}
}
]), dynamic([
{
"rel": "System.LinkTypes.Hierarchy-Forward",
"url": "https://dev.azure.com/xxxx/a69ffa35-e99f-42ea-a254/_apis/wit/workItems/247970",
"attributes": {
"isLocked": false,
"name": "Child"
}
},
{
"rel": "System.LinkTypes.Hierarchy-Forward",
"url": "https://dev.azure.com/xxxx/a69ffa35-e99f-42ea-a254/_apis/wit/workItems/242838",
"attributes": {
"isLocked": false,
"name": "Child"
}
},
{
"rel": "System.LinkTypes.Hierarchy-Forward",
"url": "https://dev.azure.com/xxxx/a69ffa35-e99f-42ea-a254/_apis/wit/workItems/242835",
"attributes": {
"isLocked": false,
"name": "Child"
}
}
]),
]
| mv-apply d on (
parse d with * "/workItems/" item:long *
| extend link = tostring(d.attributes.name)
)
| project item, link
item
link
197138
Parent
234449
Parent
247970
Child
242838
Child
242835
Child

Related

Parsing a list of images from NOTION database to flutter app

I am trying to display Notion content such as texts, dates, booleans and images on flutter app.. For texts, dates, and booleans, everything is working.. but I am stuck at displaying images. Please kindly take a look at my JSON file and my code.. and let me know where I am doing wrong..
JSON file that I got from my Notion database
{
"object": "list",
"results": [
{
"object": "page",
"id": "0f2aad20-225a-4d40-b853-fb5943e01636",
"created_time": "2022-09-01T05:14:00.000Z",
"last_edited_time": "2022-09-03T09:56:00.000Z",
"created_by": {
"object": "user",
"id": "33138aa4-0670-49f9-a118-daaef0698369"
},
"last_edited_by": {
"object": "user",
"id": "33138aa4-0670-49f9-a118-daaef0698369"
},
"cover": null,
"icon": null,
"parent": {
"type": "database_id",
"database_id": "f24cee3c-bd2f-466a-bc5f-a505e83b348f"
},
"archived": false,
"properties": {
"Price Range": {
"id": "BiJQ",
"type": "select",
"select": {
"id": "]erF",
"name": "< 2000 Lakh",
"color": "default"
}
},
"On Market": {
"id": "Bxp%60",
"type": "checkbox",
"checkbox": false
},
"Longitude ": {
"id": "CGYh",
"type": "number",
"number": 96.113146
},
"Asking Price in Lakh": {
"id": "Gv%7D%7D",
"type": "number",
"number": 590
},
"Township": {
"id": "MP%7D%3D",
"type": "select",
"select": {
"id": "qwfy",
"name": "Mingaladon - YGN",
"color": "default"
}
},
"Owner Phone": {
"id": "Mqhp",
"type": "phone_number",
"phone_number": "09448840549"
},
"Images": {
"id": "OLC%3B",
"type": "files",
"files": [
{
"name": "31_AUG-22.jpg",
"type": "file",
"file": {
"url": "https://s3.us-west-2.amazonaws.com/secure.notion-static.com/04b39e7e-c2c4-4ccd-a653-348933fa613e/31_AUG-22.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45EIPT3X45%2F20220903%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20220903T102952Z&X-Amz-Expires=3600&X-Amz-Signature=2db13c256bfd191fc3fbc0941438a4a1c75a8da128b6f69b6e2a63002140327b&X-Amz-SignedHeaders=host&x-id=GetObject",
"expiry_time": "2022-09-03T11:29:52.168Z"
}
},
{
"name": "31_AUG-21.jpg",
"type": "file",
"file": {
"url": "https://s3.us-west-2.amazonaws.com/secure.notion-static.com/06ce697d-af96-4f3e-b26e-bc092cacfdf8/31_AUG-21.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45EIPT3X45%2F20220903%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20220903T102952Z&X-Amz-Expires=3600&X-Amz-Signature=33d5c21d71113008f3fbc4f95bf311515e4d42a3eb1f8c6c10fccc355e4e2d9a&X-Amz-SignedHeaders=host&x-id=GetObject",
"expiry_time": "2022-09-03T11:29:52.209Z"
}
},
{
"name": "31_AUG-23.jpg",
"type": "file",
"file": {
"url": "https://s3.us-west-2.amazonaws.com/secure.notion-static.com/32ec9466-fe8a-4eb9-8c1b-0d0abbe8637b/31_AUG-23.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45EIPT3X45%2F20220903%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20220903T102952Z&X-Amz-Expires=3600&X-Amz-Signature=059545c77b9a2330483d34292d2b7e4503d3e9f7ceac67cd44f63d56d6d8a0f0&X-Amz-SignedHeaders=host&x-id=GetObject",
"expiry_time": "2022-09-03T11:29:52.271Z"
}
}
]
},
"Zone": {
"id": "O_ui",
"type": "select",
"select": {
"id": "bWGg",
"name": "13",
"color": "default"
}
},
"Progress": {
"id": "P%3C%7BM",
"type": "multi_select",
"multi_select": []
},
"Category": {
"id": "PM%5EA",
"type": "select",
"select": {
"id": "kLgI",
"name": "Residential",
"color": "default"
}
},
"Status": {
"id": "R%7B%5Dl",
"type": "select",
"select": {
"id": ":huS",
"name": "For Sale",
"color": "default"
}
},
"Latitude ": {
"id": "TUmm",
"type": "number",
"number": 16.955839
},
"Flooring": {
"id": "U%3FS%5D",
"type": "rich_text",
"rich_text": []
},
"Bathroom": {
"id": "WPEe",
"type": "number",
"number": 1
},
"Price Per Sqft": {
"id": "%5C%3Alg",
"type": "number",
"number": 21000
},
"Address": {
"id": "%5DSz%7C",
"type": "rich_text",
"rich_text": [
{
"type": "text",
"text": {
"content": "Mingalardon, ဝါယာလက် , တောတိုက်ရပ်ကွက်, အမှတ် ၇/၄၉",
"link": null
},
"annotations": {
"bold": false,
"italic": false,
"strikethrough": false,
"underline": false,
"code": false,
"color": "default"
},
"plain_text": "Mingalardon, ဝါယာလက် , တောတိုက်ရပ်ကွက်, အမှတ် ၇/၄၉",
"href": null
}
]
},
"Type": {
"id": "%5E%3E%40F",
"type": "select",
"select": {
"id": "Hb_}",
"name": "House",
"color": "default"
}
},
"State": {
"id": "%5E%7DP%60",
"type": "select",
"select": {
"id": ":fMv",
"name": "YGN",
"color": "default"
}
},
"Year Built": {
"id": "a%5C%5Ce",
"type": "number",
"number": 2014
},
"Data Source": {
"id": "awp%5B",
"type": "select",
"select": {
"id": "Ohch",
"name": "Facebook",
"color": "default"
}
},
"Electricity": {
"id": "bCpc",
"type": "select",
"select": {
"id": "=^]Q",
"name": "1 Single",
"color": "default"
}
},
"Cover Photo": {
"id": "bDDW",
"type": "files",
"files": [
{
"name": "31_AUG-21.jpg",
"type": "file",
"file": {
"url": "https://s3.us-west-2.amazonaws.com/secure.notion-static.com/b2784859-34d3-41c2-a88a-3311d8886804/31_AUG-21.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45EIPT3X45%2F20220903%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20220903T102952Z&X-Amz-Expires=3600&X-Amz-Signature=eb7ab8e22917357922dfa939c250c5106f8e496888b564f17c622d804045f4ff&X-Amz-SignedHeaders=host&x-id=GetObject",
"expiry_time": "2022-09-03T11:29:52.297Z"
}
}
]
},
"Contact": {
"id": "d_%5E%3E",
"type": "relation",
"relation": []
},
"Car Parking": {
"id": "gIBP",
"type": "number",
"number": 2
},
"Water System": {
"id": "gfRJ",
"type": "multi_select",
"multi_select": [
{
"id": "08a52b0a-cbbf-4e7d-8756-c2edb40a8ed9",
"name": "ဂျိုးဖြူရေ",
"color": "gray"
}
]
},
"Sold Date": {
"id": "giQA",
"type": "date",
"date": null
},
"Air Con": {
"id": "mP%5Dd",
"type": "number",
"number": 0
},
"Bedrooms": {
"id": "ptfQ",
"type": "select",
"select": {
"id": "O}`U",
"name": "3",
"color": "default"
}
},
"Owner Direct": {
"id": "py%40O",
"type": "checkbox",
"checkbox": false
},
"Lot Size (Sqft)": {
"id": "t%3AwQ",
"type": "number",
"number": 2795
},
"Type of Ownership": {
"id": "vgED",
"type": "select",
"select": {
"id": "37a4fbaa-955f-48d0-9a4d-4f5a28a8ca9a",
"name": "အရပ်စာချုပ်",
"color": "red"
}
},
"Added Time": {
"id": "x%3Byd",
"type": "last_edited_time",
"last_edited_time": "2022-09-03T09:56:00.000Z"
},
"ခြံအကျယ် (ပေ)": {
"id": "z%3D%3D%40",
"type": "rich_text",
"rich_text": [
{
"type": "text",
"text": {
"content": "43x65",
"link": null
},
"annotations": {
"bold": false,
"italic": false,
"strikethrough": false,
"underline": false,
"code": false,
"color": "default"
},
"plain_text": "43x65",
"href": null
}
]
},
"Structure": {
"id": "%7Cj%5Er",
"type": "select",
"select": {
"id": "ad149505-37a9-4464-8d13-7ff1e34cef3f",
"name": "ပျဉ်ထောင်အိမ်",
"color": "blue"
}
},
"Property Title": {
"id": "%7Cn%3F%3E",
"type": "rich_text",
"rich_text": [
{
"type": "text",
"text": {
"content": "မင်္ဂလာဒုံမြို့နယ်တောတိုက်ရပ်ကွက် ရှိ အိမ်လေးတစ်လုံးရောင်းရန်ရှိ",
"link": null
},
"annotations": {
"bold": false,
"italic": false,
"strikethrough": false,
"underline": false,
"code": false,
"color": "default"
},
"plain_text": "မင်္ဂလာဒုံမြို့နယ်တောတိုက်ရပ်ကွက် ရှိ အိမ်လေးတစ်လုံးရောင်းရန်ရှိ",
"href": null
}
]
},
"360 Photo ": {
"id": "~yOp",
"type": "url",
"url": "https://kuula.co/share/collection/7vSsM?logo=0&info=1&fs=1&vr=0&sd=1&thumbs=1"
},
"Name": {
"id": "title",
"type": "title",
"title": [
{
"type": "text",
"text": {
"content": "YGN-13C-06",
"link": null
},
"annotations": {
"bold": false,
"italic": false,
"strikethrough": false,
"underline": false,
"code": false,
"color": "default"
},
"plain_text": "YGN-13C-06",
"href": null
}
]
}
},
"url": "https://www.notion.so/YGN-13C-06-0f2aad20225a4d40b853fb5943e01636"
},
How I get data from Notion
class NotionAPI {
final http.Client _client;
static const String _baseUrl = 'https://api.notion.com/v1/';
NotionAPI({http.Client? client}) : _client = client ?? http.Client();
void dispose() {
_client.close();
}
Future<List<NotionPropertyModel>> getProperties() async {
try {
final url =
'${_baseUrl}databases/${dotenv.env['NOTION_DATABASE_ID']}/query';
final response = await _client.post(
Uri.parse(url),
headers: {
HttpHeaders.authorizationHeader:
'Bearer ${dotenv.env['NOTION_API_KEY']}',
'Notion-Version': '2022-06-28',
},
);
if (response.statusCode == 200) {
final data = jsonDecode(response.body) as Map<String, dynamic>;
return (data['results'] as List)
.map((e) => NotionPropertyModel.fromMap(e))
.toList()
..sort((a, b) => b.date.compareTo(a.date));
} else {
throw const Failure(message: 'Something went wrong..STW!');
}
} catch (_) {
throw const Failure(message: 'Something went wrong..++++!');
}
}
}
My fromJson method
factory NotionPropertyModel.fromMap(Map<String, dynamic> map) {
final properties = map['properties'] as Map<String, dynamic>;
final dateStr = properties['Date']?['date']?['start'];
return NotionPropertyModel(
pptID: properties['Name']?['title']?[0]?['plain_text'] ?? '?',
date: dateStr != null ? DateTime.parse(dateStr) : DateTime.now(),
dataSource: properties['Data Source']?['select']?['name'] ?? 'Any',
ownerDirect: properties['Owner Direct']?['checkbox'] as bool,
priceInLakh:
(properties['Asking Price in Lakh']?['number'] ?? 0).toDouble(),
coverPhoto: properties['Cover Photo']?['files']?['file']?['url'],
);
}
How I display on the screen
child: Column(
children: [
Image.network(itemData.coverPhoto),
Text(itemData.pptID),
Text(itemData.dataSource),
if (itemData.ownerDirect == true)
const Text(
'Owner Direct',
style: TextStyle(fontSize: 20),
)
],
),
Your cover image is a list of file so change this:
coverPhoto: properties['Cover Photo']?['files']?['file']?['url'],
to
factory NotionPropertyModel.fromMap(Map<String, dynamic> map) {
final properties = map['properties'] as Map<String, dynamic>;
final dateStr = properties['Date']?['date']?['start'];
List coverList = properties['Cover Photo']?['files'] ?? [];
return NotionPropertyModel(
pptID: properties['Name']?['title']?[0]?['plain_text'] ?? '?',
date: dateStr != null ? DateTime.parse(dateStr) : DateTime.now(),
dataSource: properties['Data Source']?['select']?['name'] ?? 'Any',
ownerDirect: properties['Owner Direct']?['checkbox'] as bool,
priceInLakh:
(properties['Asking Price in Lakh']?['number'] ?? 0).toDouble(),
coverPhoto: (coverList != null && coverList.isNotEmpty) ? coverList[0]['file']?['url'] : '',
);
}

Loop through a query to pull substrings in KQL/Grafana?

So I need to pull the some substrings from the following data from a query
[
{
"rel": "System.LinkTypes.Hierarchy-Forward",
"url": "https://fakelink/workItems/247155",
"attributes": {
"isLocked": false,
"name": "Child"
}
},
{
"rel": "System.LinkTypes.Hierarchy-Forward",
"url": "https://fakelink/workItems/247154 ",
"attributes": {
"isLocked": false,
"name": "Child"
}
},
{
"rel": "System.LinkTypes.Hierarchy-Forward",
"url": "https://fakelink/247160",
"attributes": {
"isLocked": false,
"name": "Child"
}
},
{
"rel": "System.LinkTypes.Hierarchy-Forward",
"url": "https://fakelink/247156",
"attributes": {
"isLocked": false,
"name": "Child"
}
},
{
"rel": "System.LinkTypes.Hierarchy-Forward",
"url": "https://fakelink/workItems/247159",
"attributes": {
"isLocked": false,
"name": "Child"
}
},
{
"rel": "System.LinkTypes.Hierarchy-Forward",
"url": "https://fakelink/workItems/247157",
"attributes": {
"isLocked": false,
"name": "Child"
}
},
{
"rel": "System.LinkTypes.Hierarchy-Forward",
"url": "https://fakelink/247158",
"attributes": {
"isLocked": false,
"name": "Child"
}
}
]
In grafana obviously having that long string in a table is useless to me. I need to somehow parse the data and pull the number at the end of each web link as well as the "Child" phrases and somehow connect those preferably as a Child column (or whatever phrase is in that spot) with the numbers at the end of the web links being the data in the table. I was told I needed to "write a loop to go through the JSON" any help at all, suggestions, anything, would be massively appreciated
note: the string is different for every single item the query pulled up and there's a couple thousand
mv-expand operator, to explode the array.
parse operator, to extract the number from each url.
datatable(doc:dynamic)[dynamic([ { "rel": "System.LinkTypes.Hierarchy-Forward", "url": "https://fakelink/workItems/247155", "attributes": { "isLocked": false, "name": "Child" } }, { "rel": "System.LinkTypes.Hierarchy-Forward", "url": "https://fakelink/workItems/247154 ", "attributes": { "isLocked": false, "name": "Child" } }, { "rel": "System.LinkTypes.Hierarchy-Forward", "url": "https://fakelink/247160", "attributes": { "isLocked": false, "name": "Child" } }, { "rel": "System.LinkTypes.Hierarchy-Forward", "url": "https://fakelink/247156", "attributes": { "isLocked": false, "name": "Child" } }, { "rel": "System.LinkTypes.Hierarchy-Forward", "url": "https://fakelink/workItems/247159", "attributes": { "isLocked": false, "name": "Child" } }, { "rel": "System.LinkTypes.Hierarchy-Forward", "url": "https://fakelink/workItems/247157", "attributes": { "isLocked": false, "name": "Child" } }, { "rel": "System.LinkTypes.Hierarchy-Forward", "url": "https://fakelink/247158", "attributes": { "isLocked": false, "name": "Child" } } ])]
| mv-expand doc
| project doc.url
| parse doc_url with * "/" num:long
doc_url
num
https://fakelink/workItems/247155
247155
https://fakelink/workItems/247154
247154
https://fakelink/247160
247160
https://fakelink/247156
247156
https://fakelink/workItems/247159
247159
https://fakelink/workItems/247157
247157
https://fakelink/247158
247158
Fiddle

Xquery How to get the name of the song where the available_markets contains more elements than 2

I have a JSON file with information about 100 Spotify artist. I am trying to get the name of the songs where the "availabla_markets" contains more elements than 2.
Example:
{
"href": "https://api.spotify.com/v1/playlists/37i9dQZF1DX2RxBh64BHjQ/tracks?offset=0&limit=100&additional_types=track",
"items": [
{
"added_at": "2021-11-29T23:29:54Z",
"added_by": {
"external_urls": {
"spotify": "https://open.spotify.com/user/"
},
"href": "https://api.spotify.com/v1/users/",
"id": "",
"type": "user",
"uri": "spotify:user:"
},
"is_local": false,
"primary_color": null,
"track": {
"album": {
"album_type": "single",
"artists": [
{
"external_urls": {
"spotify": "https://open.spotify.com/artist/0Njy6yR9LykNKYg9yE23QN"
},
"href": "https://api.spotify.com/v1/artists/0Njy6yR9LykNKYg9yE23QN",
"id": "0Njy6yR9LykNKYg9yE23QN",
"name": "Nardo Wick",
"type": "artist",
"uri": "spotify:artist:0Njy6yR9LykNKYg9yE23QN"
}
],
"available_markets": [
"AD",
"AE"
],
"external_urls": {
"spotify": "https://open.spotify.com/album/6SEeNB2xGW1kmysKSvWYqC"
},
"href": "https://api.spotify.com/v1/albums/6SEeNB2xGW1kmysKSvWYqC",
"id": "6SEeNB2xGW1kmysKSvWYqC",
"name": "Me or Sum (feat. Future & Lil Baby)",
},
"artists": [
{
"external_urls": {
"spotify": "https://open.spotify.com/artist/0Njy6yR9LykNKYg9yE23QN"
},
"name": "Nardo Wick",
}
],
"available_markets": [
"AD",
"AE",
"AG",
"AL",
],
"disc_number": 1,
"duration_ms": 225664,
"external_urls": {
"spotify": "https://open.spotify.com/track/1qlh1WxuWilyIWRwdsKMuJ"
},
"name": "Me or Sum (feat. Future & Lil Baby)",
},
}
}
How can I return the name of the songs(eg:"Me or Sum (feat. Future & Lil Baby)") where the "available_markets" contains more elements than 2 using Xquery?
json-doc('xxx')?items?*?track[count(?available_markets?*) gt 2]?name

Extract parent node by filtering on child nodes

I need to filter JSON on some child elements and to extract the parent node id.
Part of the JSON:
[
{
"data": {
"id": "2da44298-05ec-4bb5-acce-b524ef56328c",
"attributes": {
"units": [
{
"id": "1492de82-2f36-43bf-b077-5cf54a3f38b9",
"show_name": false,
"children": [
{
"id": "a5d76efa-5b21-4874-a8a5-c9c9f8317ee6",
"contents": [
{
"id": "b96c127c-6a4f-4a29-924d-63f0ba55972a",
"link": {
"url": "#",
"target": "_blank",
"data": {
"aspect-ratio": null
}
},
"duration": null
},
{
"id": "dbb7e8fd-aa35-4acc-8ad7-1c7dcd08a6d8",
"link": {
"data": {
"id": "dbb7e8fd-aa35-4acc-8ad7-1c7dcd08a6d8",
"aspect-ratio": null
}
},
"duration": null
}
]
},
{
"id": "8a805cd0-7447-4fac-b4fc-aaa9a2f7e649",
"contents": [
{
"id": "d64138b6-5195-48b4-a0f7-b087c5496587",
"link": {
"data": {
"id": "d64138b6-5195-48b4-a0f7-b087c5496587",
"aspect-ratio": null
}
},
"duration": null
},
{
"id": "392406b1-fa20-413b-a98a-4d1a5b201d8e",
"link": {
"url": "#",
"target": "_blank",
"data": {
"id": "423498d9-8e0f-41ef-891a-34b078862ce7",
"aspect-ratio": null
}
},
"duration": null
}
]
}
],
"contents": []
}
],
"text": []
}
},
"jsonapi": {
"version": "1.0"
}
}
]
For example, it is required to extract unit id filtered on contents id b96c127c-6a4f-4a29-924d-63f0ba55972
I tried the following expressions:
$..data..?(#contents.data.id == 'b96c127c-6a4f-4a29-924d-63f0ba55972a')].id
$..data..?(#contents.data.id == 'b96c127c-6a4f-4a29-924d-63f0ba55972a')].children.id
$..data..?(#contents.data.id == 'b96c127c-6a4f-4a29-924d-63f0ba55972a')].unit.id
I need to do this way because of those ids are being got from different responses.
You could use nested filter operators to get the parent node, something like:
$..data.attributes.units.[?(#.children[?(#.content[?(#.id == 'b96c127c-6a4f-4a29-924d-63f0ba55972')])])].id
Demo:
More information: JMeter's JSON Path Extractor Plugin - Advanced Usage Scenarios

EmberJS JSONAPIAdapter with hasMany + embedded relationships

In addition to my last question ember.js JSONAPIAdapter with hasMany a colleague asked if the "kind-of"-sideloaded relationships in the working
JSON:API structure could be embedded like this:
{
"data": [
{
"type": "altersgruppe",
"id": "1",
"attributes": {
"name": "UNTER_21"
},
"relationships": {
"tarifbeitraege": {
"data": [
{
"type": "tarifbeitrag",
"id": "3",
"attributes": {
"name": "ZAHN70",
"beitrag": "3-29,70",
"proergaenzung": "7,00",
"gesamtbeitrag": "25.99"
}
},
{
"type": "tarifbeitrag",
"id": "4",
"attributes": {
"name": "ZAHN90",
"beitrag": "4-28,70",
"proergaenzung": "7,00",
"gesamtbeitrag": "30.99"
}
}
]
}
}
},
{
"type": "altersgruppe",
"id": "2",
"attributes": {
"name": "ALTER_21_24"
},
"relationships":{
"tarifbeitraege": {
"data": [
{
"type": "tarifbeitrag",
"id": "1",
"attributes": {
"name": "ZAHN70",
"beitrag": "1-25,70",
"proergaenzung": "7,00",
"gesamtbeitrag": "25.99"
}
},
{
"type": "tarifbeitrag",
"id": "2",
"attributes": {
"name": "ZAHN90",
"beitrag": "2-25,70",
"proergaenzung": "7,00",
"gesamtbeitrag": "25.99"
}
}]
}
}
}
]
}
The idea behind that: We can use relationships with less problems in the java backend (where sideloaded structures are harder to implement).
But the JSON above structure does not work. The store contains only the first level of data, which is "altersgruppe", but "tarifbeitraege" are empty.
This type of document is referred to as a compound document in the JSON:API specification.
The "relationships" section of a compound document is supposed to have only the relationships - individual objects there are supposed to be resource identifier objects. Putting attributes there doesn't work because that's not where they are supposed to be.
Instead, the full objects are side-loaded in a top-level "included" section. Thus, your response should probably look more like this:
{
"data": [
{
"type": "altersgruppe",
"id": "1",
"attributes": {
"name": "UNTER_21"
},
"relationships": {
"tarifbeitraege": {
"data": [
{ "type": "tarifbeitrag", "id": "3" },
{ "type": "tarifbeitrag", "id": "4" }
]
}
}
},
{
"type": "altersgruppe",
"id": "2",
"attributes": {
"name": "ALTER_21_24"
},
"relationships":{
"tarifbeitraege": {
"data": [
{ "type": "tarifbeitrag", "id": "1" },
{ "type": "tarifbeitrag", "id": "2" }
]
}
}
}
],
"included": [
{
"type": "tarifbeitrag",
"id": "3",
"attributes": {
"name": "ZAHN70",
"beitrag": "3-29,70",
"proergaenzung": "7,00",
"gesamtbeitrag": "25.99"
}
},
{
"type": "tarifbeitrag",
"id": "4",
"attributes": {
"name": "ZAHN90",
"beitrag": "4-28,70",
"proergaenzung": "7,00",
"gesamtbeitrag": "30.99"
}
},
{
"type": "tarifbeitrag",
"id": "1",
"attributes": {
"name": "ZAHN70",
"beitrag": "1-25,70",
"proergaenzung": "7,00",
"gesamtbeitrag": "25.99"
}
},
{
"type": "tarifbeitrag",
"id": "2",
"attributes": {
"name": "ZAHN90",
"beitrag": "2-25,70",
"proergaenzung": "7,00",
"gesamtbeitrag": "25.99"
}
}
]
}
There's an example on the home page of http://jsonapi.org that shows an example that includes a side load, as well as one in the section of the specification describing compound documents.