AWS IoT rule sql select statement - sql

I am trying to write a SQL select statement for my AWS IoT rule to extract the values 'gateway_id and 'rssi' from the following MQTT message:
{
"end_device_ids": {
"device_id": "imd2",
"application_ids": {
"application_id": "pennal"
},
"dev_eui": "004E3A0DF76DC9E9",
"join_eui": "70B3D57ED003CBE8",
"dev_addr": "260BA9D0"
},
"correlation_ids": [
"as:up:01G30W0J4D65P6D50QH1DN3ZQP",
"gs:conn:01G2ZZ7FT9BH6J93WRYS4ATVDM",
"gs:up:host:01G2ZZ7FTN14103H90QN71Q557",
"gs:uplink:01G30W0HXWMES1Z7X7F2MCFMPF",
"ns:uplink:01G30W0HXXJM5PNGJAD0W01GGH",
"rpc:/ttn.lorawan.v3.GsNs/HandleUplink:01G30W0HXWFR3HNGBZS7XJV15E",
"rpc:/ttn.lorawan.v3.NsAs/HandleUplink:01G30W0J4D18JZW199EM8WERGR"
],
"received_at": "2022-05-14T08:47:25.837680984Z",
"uplink_message": {
"session_key_id": "AYBlRLSz9n83bW3WU3+GfQ==",
"f_port": 1,
"f_cnt": 5013,
"frm_payload": "DiAAAA==",
"decoded_payload": {
"rainmm": 0,
"voltage": 3.616
},
"rx_metadata": [
{
"gateway_ids": {
"gateway_id": "pennal-gw2",
"eui": "AC1F09FFFE057EC6"
},
"time": "2022-05-14T08:47:25.065794944Z",
"timestamp": 114306297,
"rssi": -126,
"channel_rssi": -126,
"snr": -8.25,
"uplink_token": "ChgKFgoKcGVubmFsLWd3MhIIrB8J//4FfsYQ+dnANhoMCJ3Z/ZMGEOPmv6sCIKjZvump7gYqCwid2f2TBhCA568f"
}
],
"settings": {
"data_rate": {
"lora": {
"bandwidth": 125000,
"spreading_factor": 11
}
},
"coding_rate": "4/5",
"frequency": "868100000",
"timestamp": 114306297,
"time": "2022-05-14T08:47:25.065794944Z"
},
"received_at": "2022-05-14T08:47:25.629041670Z",
"confirmed": true,
"consumed_airtime": "0.659456s",
"version_ids": {
"brand_id": "heltec",
"model_id": "cubecell-dev-board-class-a-otaa",
"hardware_version": "_unknown_hw_version_",
"firmware_version": "1.0",
"band_id": "EU_863_870"
},
"network_ids": {
"net_id": "000013",
"tenant_id": "ttn",
"cluster_id": "eu1",
"cluster_address": "eu1.cloud.thethings.network"
}
}
}
I have tried following the documentation here: AWS Documentation but am struggling with the nested part of the message.
my SQL statement at the moment is:
SELECT received_at as datetime, end_device_ids.device_id as device_id,
uplink_message.decoded_payload.rainmm as rainmm, uplink_message.decoded_payload.voltage as
voltage, uplink_message.settings.data_rate.lora.spreading_factor as sprfact,
uplink_message.consumed_airtime as time_on_air ,uplink_message.settings.timestamp as ts,
uplink_message.rx_metadata as rx,(select value gateway_ids from uplink_message.rx_metadata) as gw,
(select value rssi from uplink_message.rx_metadata)as rssi, get((select gateway_id from
uplink_message.rx_metadata),0).gateway_id as gwn FROM 'thethings/lorawan/matt-pennal-ire/uplink'
which returns
{
"datetime": "2022-05-15T12:19:11.947844474Z",
"device_id": "md4",
"rainmm": 5.842001296924288,
"voltage": 3.352,
"sprfact": 8,
"time_on_air": "0.092672s",
"ts": 3262497863,
"rx": [
{
"gateway_ids": {
"gateway_id": "pennal-gw2",
"eui": "AC1F09FFFE057EC6"
},
"time": "2022-05-15T12:19:11.178463935Z",
"timestamp": 3262497863,
"rssi": -125,
"channel_rssi": -125,
"snr": -7.5,
"uplink_token": "ChgKFgoKcGVubmFsLWd3MhIIrB8J//4FfsYQx4jXkwwaDAi/34OUBhCCy9XhAiDY6prg+ckHKgsIv9+DlAYQv8mMVQ=="
}
],
"gw": [
{
"gateway_id": "pennal-gw2",
"eui": "AC1F09FFFE057EC6"
}
],
"rssi": [
-125
]
}
but I would like it to return
{
"datetime": "2022-05-15T12:19:11.947844474Z",
"device_id": "md4",
"rainmm": 5.842001296924288,
"voltage": 3.352,
"sprfact": 8,
"time_on_air": "0.092672s",
"ts": 3262497863,
"gwn":"pennal_gw2"
"rssi":-126
}
Any help to get the values from the nested array would be greatly appreciated!

Related

GetBlock and all related methods doesn't return an info about transactions

Usually, tronGrid returns blocks with transactions, but as I found today, it's not behaving as needed.
How it works right now:
{
"blockID": "0000000001b16eb8b97ab73b7dc8f161c5f2f786f0937bfed7886baa33926c84",
"block_header": {
"raw_data": {
"number": 28405432,
"txTrieRoot": "0000000000000000000000000000000000000000000000000000000000000000",
"witness_address": "41f16412b9a17ee9408646e2a21e16478f72ed1e95",
"parentHash": "0000000001b16eb7a6f39a1523f35db8b4089d5a03f591958beafd139e0949d5",
"version": 24,
"timestamp": 1666102851000
},
"witness_signature": "60c7b8b964f103072b7e0fd33b5df636ef4e06d95bb113184ef3266b691b2cf517091960aba72dcd8d5a1ee40374f2124256ddad445429897b066332964ef8d500"
}
}
And how it works before:
{
"blockID": "0000000001b15f18976aee56ff9490303ec64c2007d6034ca03a7a2caefdab73",
"block_header": {
"raw_data": {
"number": 28401432,
"txTrieRoot": "167b9b1620d76e9855d426453ea726a709582f4ed711701ee22fe730bae3f8d8",
"witness_address": "41cd8d8ad1b4a5bd7afe46949421d2b411a3601717",
"parentHash": "0000000001b15f175dc2a20b8c3b29bbbb50860dc57d54d44eff4b02edf849e6",
"version": 24,
"timestamp": 1666089210000
},
"witness_signature": "b9239d12b2044b1bdfa631115f3c7b9b1c1fc5d37c482809d2c7846d05ab84d61778910a55501f4702fe653b943b22b9270b33151ec15e35aa500388dac0abda01"
},
"transactions": [
{
"ret": [
{
"contractRet": "SUCCESS"
}
],
"signature": [
"56a427e32fc0267a2e469ef85530c3145c7de423c8f20d7e11d85dbff98701bdd599d5a45b58ab4f7fa7f212c2ee3cbb5daa50541a83f67dbff533b7e185331501"
],
"txID": "5fd2335105f68de47b82fe3f8065cb3d1cc8ab437aaee55a5d4e61624113730b",
"raw_data": {
...
},
"raw_data_hex": "0a025f0522084cf822e1795ff17f40a7e6a2d5be305a67080112630a2d747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e73666572436f6e747261637412320a1541989cc89d2df684c69bed3563c0cd8817be0a11e1121541bc0777bd8f50e5e148ef59bdce2b895b754c452e1888890a70c7919fd5be30"
}
]
}
Is there a new feature, or it's a bug?

How to avoid the duplicated data entry after parsing json in kusto?

I have following sample json data.
{
"data": {
"type": "ABC",
"id": "17495500314",
"attributes": {
[!["event": "update",
"gps_vali][1]][1]d": true,
"gps": {
"distance_diff": 6.48,
"total_distance": 848.6
},
"hdop": 79,
"fuel_level": 46.8,
"total_fuel_used": 60443.9,
"location": {
"latitude": 411.372618,
"longitude": -1.254931,
"relative_position": {
"distance": "37",
}
},
"idle_periods": []
},
"relationships": {
"assets": {
"data": [
{
"type": "ABCDFTTG",
"id": "1589799143500003",
"attributes": {
"external_id": "ABCDFTTG",
"hardware_id": "ABCDFTTG"
}
}
]
},
"devices": {
"data": [
{
"type": "ABCDFTTG",
"id": "1585231172900341",
"attributes": {
"serial": "5572016191"
}
},
{
"type": "tablet",
"id": "1587893062600175",
"attributes": {
"serial": "ABCDFTTG"
}
}
]
},
"users": {
"data": [
{
"type": "user",
"id": "ABCDFTTG",
"attributes": {
"external_id": "ABCDFTTG"
}
}
]
}
}
},
"meta": {
"message_id": "11eb-8c75-0b3f87aedbb5",
"consumer_version": "1.2.0",
"origin_version": null,
"timestamp": "2021-06-14T17:42:29Z"
}
}
I want only one row instead of this two. Here is my kusto query which is used for parsing json data into table columns.
Test
|where messageId =="123"
//|mv-expand message=message.data.attributes
|mv-expand message
|mv-expand Value=message.data.relationships.assets.['data']
|mv-expand value_devices=message.data.relationships.devices.['data']
|mv-expand value_user=message.data.relationships.users.['data']
| project type=message.data.type,id=message.data.id,
event=tostring(message.data.attributes.event),
logged_at=tostring(message.data.attributes.logged_at),
distance=toint(message.data.attributes.location.relative_position.distance),
// Value=message.data.relationships.assets.['data'],//.['data']
type_asset=Value.type,asset_id=Value.id,
device_type=value_devices.type,device_id=value_devices.id,
device_attr_serial=value_devices.attributes.serial,
user_type=value_user.type,user_id=value_user.id,
user_external_id=value_user.attributes.external_id
This duplicate row appeared after adding user tag this tag is array so how to handle this array with single id.
I have parse my json data any got the following output.
Expected output should be like
check device_type and device_id columns

How can I define jsonPath for given json?

{
"name": "ninja",
"contry": "India",
"Account": [
{
"id": "123",
"orgId": 223,
"investment": [
{
"invetmentId": "111",
"name": "India tech",
"performance": [
{
"id": "123",
"performanceSet": [
{
"amount": "231",
"currency": "USD"
},
{
"amount": "250",
"currency": "IND"
}
]
}
]
}
]
}
]
}
So I have to select the amount where the currency is USD?
And I tried it as "$.Account..investment.performance..performanceSet.amount[?(#.currency=~/.*USD/)]"
This JsonPath should work:
$..performanceSet[?(#.currency == "USD")].amount
Tested on:
{
"name":"ninja",
"contry":"India",
"Account":[
{
"id":"123",
"orgId":223,
"investment":[
{
"invetmentId":"111",
"name":"India tech",
"performance":[
{
"id":"123",
"performanceSet":[
{
"amount":"231",
"currency":"USD"
},
{
"amount":"250",
"currency":"IND"
}
]
}
]
},
{
"invetmentId":"112",
"name":"India tech 2",
"performance":[
{
"id":"124",
"performanceSet":[
{
"amount":"235",
"currency":"USD"
},
{
"amount":"250",
"currency":"IND"
}
]
}
]
}
]
}
]
}
which returns:
[
"231",
"235"
]
A good way to try it out is this site: https://jsonpath.com/
Read the docs: https://github.com/intuit/karate#jsonpath-filters
* def temp = $..performanceSet[?(#.currency=='USD')]
* match temp[0].amount == '231'
You can try it this way
$.Account..investment.performance..performanceSet.amount[?(#.currency=~/.*USD/)]

Error when creating a chart via a batch request

I'm trying to create a new chart, following the examples presented in Google sheets API. I'm getting the following error:
HttpError 400 when requesting
https://slides.googleapis.com/v1/presentations/PRESENTATION_ID:batchUpdate?alt=json
returned "Invalid JSON payload received. Unknown name "add_chart" at
'requests[0]': Cannot find field."
Has anyone encountered this before?
Other requests are working normal (replace text, add text, clone presentation, etc)
this request is being copied from the example in Google sheets API.
sourceSheetId is the id where I have the data for the chart saved in.
{
"addChart": {
"chart": {
"spec": {
"title": "Model Q1 Sales",
"basicChart": {
"chartType": "COLUMN",
"legendPosition": "BOTTOM_LEGEND",
"axis": [
{
"position": "BOTTOM_AXIS",
"title": "Model Numbers"
},
{
"position": "LEFT_AXIS",
"title": "Sales"
}
],
"domains": [
{
"domain": {
"sourceRange": {
"sources": [
{
"sheetId": sourceSheetId,
"startRowIndex": 0,
"endRowIndex": 7,
"startColumnIndex": 0,
"endColumnIndex": 1
}
]
}
}
}
],
"series": [
{
"series": {
"sourceRange": {
"sources": [
{
"sheetId": sourceSheetId,
"startRowIndex": 0,
"endRowIndex": 7,
"startColumnIndex": 1,
"endColumnIndex": 2
}
]
}
},
"targetAxis": "LEFT_AXIS"
},
{
"series": {
"sourceRange": {
"sources": [
{
"sheetId": sourceSheetId,
"startRowIndex": 0,
"endRowIndex": 7,
"startColumnIndex": 2,
"endColumnIndex": 3
}
]
}
},
"targetAxis": "LEFT_AXIS"
},
{
"series": {
"sourceRange": {
"sources": [
{
"sheetId": sourceSheetId,
"startRowIndex": 0,
"endRowIndex": 7,
"startColumnIndex": 3,
"endColumnIndex": 4
}
]
}
},
"targetAxis": "LEFT_AXIS"
}
],
"headerCount": 1
}
},
"position": {
"newSheet": True
}
}
}
}
I was expecting the chart to be created and receive a response with chartId, however I'm getting from the request a 400 status:
HttpError 400 when requesting
https://slides.googleapis.com/v1/presentations/PRESENTATION_ID:batchUpdate?alt=json
returned "Invalid JSON payload received. Unknown name "add_chart" at
'requests[0]': Cannot find field."

Nested "for loop" searches in SQL - Azure CosmosDB

I am using Cosmos DB and have a document with the following simplified structure:
{
"id1":"123",
"stuff": [
{
"id2": "stuff",
"a": {
"b": {
"c": {
"d": [
{
"e": [
{
"id3": "things",
"name": "animals",
"classes": [
{
"name": "ostrich",
"meta": 1
},
{
"name": "big ostrich",
"meta": 1
}
]
},
{
"id3": "default",
"name": "other",
"classes": [
{
"name": "green trees",
"meta": 1
},
{
"name": "trees",
"score": 1
}
]
}
]
}
]
}
}
}
}
]
}
My issue is - I have an array of these documents and need to search name to see if it matches my search word. For example I want both big trees and trees to return if a user types in trees.
So currently I push every document into an array and do the following:
For each document
for each stuff
for each a.b.c.d[0].e
for each classes
var splice = name.split(' ')
if (splice.includes(searchWord))
return id1, id2 and id3.
Using cosmosDB I am using SQL with the following code:
client.queryDocuments(
collection,
`SELECT * FROM root r`
).toArray((err, results) => {stuff});
This effectively brings every document in my collection into an array to perform the search manually above as mentioned.
This is going to cause issues when I have 1000s or 1,000,000s of documents in the array and I believe I should be leveraging the search mechanics available within Cosmos itself. Is anyone able to help me to work out what SQL query would be able to perform this type of function?
Having searched everything is it also possible to search the 5 latest documents?
Thanks for any insight in advance!
1.Is anyone able to help me to work out what SQL query would be able to
perform this type of function?
According to your sample and description, I suggest you using ARRAY_CONTAINS in cosmos db sql. Please refer to my sample:
sample documents:
[
{
"id1": "123",
"stuff": [
{
"id2": "stuff",
"a": {
"b": {
"c": {
"d": [
{
"e": [
{
"id3": "things",
"name": "animals",
"classes": [
{
"name": "ostrich",
"meta": 1
},
{
"name": "big ostrich",
"meta": 1
}
]
},
{
"id3": "default",
"name": "other",
"classes": [
{
"name": "green trees",
"meta": 1
},
{
"name": "trees",
"score": 1
}
]
}
]
}
]
}
}
}
}
]
},
{
"id1": "456",
"stuff": [
{
"id2": "stuff2",
"a": {
"b": {
"c": {
"d": [
{
"e": [
{
"id3": "things2",
"name": "animals",
"classes": [
{
"name": "ostrich",
"meta": 1
},
{
"name": "trees",
"meta": 1
}
]
},
{
"id3": "default2",
"name": "other",
"classes": [
{
"name": "green trees",
"meta": 1
},
{
"name": "trees",
"score": 1
}
]
}
]
}
]
}
}
}
}
]
},
{
"id1": "789",
"stuff": [
{
"id2": "stuff3",
"a": {
"b": {
"c": {
"d": [
{
"e": [
{
"id3": "things3",
"name": "animals",
"classes": [
{
"name": "ostrich",
"meta": 1
},
{
"name": "big",
"meta": 1
}
]
},
{
"id3": "default3",
"name": "other",
"classes": [
{
"name": "big trees",
"meta": 1
}
]
}
]
}
]
}
}
}
}
]
}
]
query :
SELECT distinct c.id1,stuff.id2,e.id3 FROM c
join stuff in c.stuff
join d in stuff.a.b.c.d
join e in d.e
where ARRAY_CONTAINS(e.classes,{name:"trees"},true)
or ARRAY_CONTAINS(e.classes,{name:"big trees"},true)
output:
2.Having searched everything is it also possible to search the 5 latest
documents?
Per my research, features like LIMIT is not supported in cosmos so far. However , TOP is supported by cosmos db. So if you could add sort field(such as date or id), then you could use sql:
select top 5 from c order by c.sort desc