DocumentDB get min of subarray - json

my json data:
[
{
"Code": "GB-00001",
"BasicInformation": {
"WGS84Longitude": -4.670000,
"WGS84Latitude": 50.340000
},
"Availability": [{
"ArrivalDate": "2017-04-21",
"Price": 689
},
{
"ArrivalDate": "2017-04-28",
"Price": 1341
}
]},
{
"Code": "GB-00002",
"BasicInformation": {
"WGS84Longitude": -4.680000,
"WGS84Latitude": 50.350000
},
"Availability": [{
"ArrivalDate": "2017-04-21",
"Price": 659
},
{
"ArrivalDate": "2017-04-28",
"Price": 1440
}
]}
}]
I'd like the result to be like:
[
{
"HouseCode": "GB-00001",
"Country": "GB",
"location": {
"type": "Point",
"coordinates": [
50.340000,
-4.670000
]
}, "lowestPrice": 689
},
{
"HouseCode": "GB-00002",
"Country": "GB",
"location": {
"type": "Point",
"coordinates": [
50.350000,
-4.680000
]
}, "lowestPrice" : 659
}
My problem is: how to use the min(c.Availability.Price)
This is my current query with the lat lng convert to point, but no idea how to get the minimum/lowest price.
SELECT c.Code, c.BasicInformation.Country ,
{"type":"Point","coordinates": [c.BasicInformation.Latitude, c.BasicInformation.Longitude]} as location
FROM c
already tried with Join c.Availability a and , min(a.Price)
edit perhaps I am too early? https://feedback.azure.com/forums/263030-documentdb/suggestions/18561901-add-group-by-support-for-aggregate-functions
found that url in https://stackoverflow.com/a/42697673/169714

This is a pretty close to ideal situation for a user defined function (UDF).
Here is one that should do the trick:
function lowestPrice(availability) {
var i, len, lowest, row;
lowest = 2e308;
for (i = 0, len = availability.length; i < len; i++) {
row = availability[i];
lowest = Math.min(lowest, row.Price);
}
return lowest;
};
You call it like this:
SELECT
c.Code,
c.BasicInformation.Country,
{"type":"Point","coordinates": [
c.BasicInformation.Latitude, c.BasicInformation.Longitude
]} as location,
udf.lowestPrice(c.Availability) as lowestPrice
FROM c

AFAIK, you could only use UDF to achieve your requirement for now. Also, I have checked the code provided by Larry Maccherone, and it could both work on Azure DocumentDB service and my DocumentDB Emulator (version 1.11.136.2) as follows:
DocumentDB.GatewayService.exe has stopped working
For DocumentDB.GatewayService crash, I assumed that you need to collect the dump files and attach them with an email to askdocdb#microsoft.com. For more details, you could refer to DocumentDB Emulator troubleshooting.

Related

Extract value of Tags from cloudTrail logs using Athena

I am trying to query cloudtrail logs using Athena. My goal is to find specific instances and extract them with their Tags.
The query I am using is:
SELECT eventTime, awsRegion , json_extract(responseelements, '$.instancesSet.items[0].instanceId') AS instanceId, json_extract(responseelements, '$.instancesSet.items[0].tagSet.items') AS TAGS FROM cloudtrail_logs_PP WHERE (eventName = 'RunInstances' OR eventName = 'StartInstances' ) AND requestparameters LIKE '%mytest1%' AND "timestamp" BETWEEN '2021/09/01' AND '2021/10/01' ORDER BY eventTime;
Using this query - I am able to get all Tags under one column.
Output of query
I want to extract only specific Tags and need help in the same. How cam I extract the only specific Tag?
I tried enhancing my query as json_extract(responseelements, '$.instancesSet.items[0].tagSet.items[0]' but the order of Tags is diff in diff logs - so cant pass the index location.
My json file in S3 is something like below:
{
"eventVersion": "1",
"eventTime": "2022-05-27T18:44:29Z",
"eventName": "RunInstances",
"awsRegion": "us-east-1",
"requestParameters": {
"instancesSet": {
"items": [{
"imageId": "ami-1234545",
"keyName": "DDKJKD"
}]
},
"instanceType": "m5.2xlarge",
"monitoring": {
"enabled": false
},
"hibernationOptions": {
"configured": false
}
},
"responseElements": {
"instancesSet": {
"items": [{
"tagSet": {
"items": [ {
"key": "11",
"value": "DS"
}, {
"key": "1",
"value": "A"
}]
}]
}
}
}

Creating nodes from nested JSON using neo4J query

I'm new in neo4j and i have this json file:
{
"locations_connections": {
"locations": [
{
"id": "aws.us-east-1",
"longitude": 72.8777,
"latitude": 19.0760
},
{
"id": "aws.us-east-2",
"longitude": 126.9780,
"latitude": 37.5665
},
{
"id": "aws.us-west-1",
"longitude": 103.8517837,
"latitude": 1.287950
}
],
"connections": [
{
"aws.us-west-1": [
{
"id": "aws.us-west-1",
"latency": 3.16,
"cost": 0.02
},
{
"id": "aws.us-east-1",
"latency": 53.47,
"cost": 0.02
},
{
"id": "aws.us-east-2",
"latency": 53.47,
"cost": 0.02
}
]
},
{
"aws.us-east-1": [
{
"id": "aws.us-east-1",
"latency": 3.16,
"cost": 0.02
},
{
"id": "aws.us-east-2",
"latency": 53.47,
"cost": 0.02
}
]
},
{
"aws.us-east-2": [
{
"id": "aws.us-east-2",
"latency": 53.47,
"cost": 0.02
}
]
}
]
}
}
After reading the json using the apoc.load.json(URL) procedure , what query do I write to represent this as a graph?
where the Node will contain the information name like for example aws.us-east-1, value of longitude and value of latitude and the edges will have the latency and the cost
I have this code:
call apoc.load.json("/file.json") yield value
UNWIND value.locations_connections.locations as loc
UNWIND value.locations_connections.connections as con
MERGE (e:Element {id:loc.id}) ON CREATE
SET e.longitude = loc.longitude, e.latitude = loc.latitude
WITH con
FOREACH (region_source IN KEYS(con)|
FOREACH (data in con[region_source]|
MERGE (e1:Element {id: region_source})
MERGE (e1)<-[:CONNECT]-(e2:Element {id:data.id, latency:data.latency, cost:data.cost})
))
and the execution result is incorrect:
Added 9 labels, created 9 nodes, set 27 properties, created 6 relationships, completed after 60 ms.and I have seen this one,But this is not what I expected
You cannot use match inside a FOREACH so when you put MERGE and :CONNECT inside the for loop, it is creating multiple nodes. This is what I did and tell us if it works for you or not.
call apoc.load.json("/file.json") yield value
// read the json file
WITH value, value.locations_connections.locations as locs
// for loop to create the locations (or regions)
FOREACH (loc in locs | MERGE (e:Element {id:loc.id}) ON CREATE
SET e.longitude = loc.longitude, e.latitude = loc.latitude
)
// get the data for the connections
WITH value.locations_connections.connections as cons
UNWIND cons as con
// the keys and value are assigned to variables region and data
WITH KEYS(con)[0] as region_source, con[KEYS(con)[0]] as dat
// unwind is similar to a for loop
UNWIND dat as data
// look for the nodes that we want
MATCH (e1:Element {id: region_source}), (e2:Element {id: data.id})
// create the connection between regions
MERGE (e1)<-[:CONNECT {latency:data.latency, cost:data.cost}]-(e2)
RETURN e1, e2
See result below:

How do I define this variable from a JSON response?

I am working with calling API data from weather providers and am trying to define a variable mtwnsd24 with the following code:
var mtwnsd24 = data.data.coordinates.dates.value[2];
$(".mtwnsd24").append(mtwnsd24);
}
);
The response, when run in Postman, gives the following JSON and I want to get the value "42.4".
"status": "OK",
"data": [
{
"parameter": "wind_speed_10m:kmh",
"coordinates": [
{
"lat": 40.014994,
"lon": -73.811646,
"dates": [
{
"date": "2020-01-04T05:00:00Z",
"value": 5.0
},
{
"date": "2020-01-05T05:00:00Z",
"value": 42.4
},
{
"date": "2020-01-06T05:00:00Z",
"value": 17.7
}
]
}
]
},
The definition nor any variations seem to work.
This should do the trick
data.data[0].coordinates[0].dates[1].value
Result is
42.4
Note that json array indexes are zero-based so if you want second element, you need to use index of 1

Insert into existing map a map structure in DynamoDB using Nodejs

Structure of an item in database is as shown below:
{
"cars": {
"x": [
{
"time": 1485700907669,
"value": 23
}
]
},
"date": 1483214400000,
"id":"1"
}
I have to add a new item "z" of type list to cars like
{
"cars": {
"x": [
{
"time": 1485700907669,
"value": 23
}
],
"z": [
{
"time": 1485700907669,
"value": 23
}
]
},
"date": 1483214400000,
"id": "1"
}
What would the update expression in Node.js look like if I want to achieve somethings like this?
So far this is what I came up with:
set #car.#model= list_append(if_not_exists(#car.#model, :empty_list), :value)
However, if the item does not exist at the time of creation it throws error. Any idea how to do this?
This is the updated parameter I am using, still doesn't work
var params = {
TableName:table,
Key:{
"id": id,
"date": time.getTime()
},
ReturnValues: 'ALL_NEW',
UpdateExpression: 'SET #car.#model = if_not_exists(#car.#model,
:empty_list)',
ExpressionAttributeNames: {
'#car': 'cars',
'#model':"z"
},
ExpressionAttributeValues: {
':empty_list': [],
}
};
The solution is to update operation in two steps, first create a empty map for the parent since it does not exist in the first place.
So, in my case
SET #car= :empty_map
where :empty_map = {}
after doing this run the other update expression
SET #car.#model = list_append(if_not_exists(#car.#model, :empty_list), :value)
where :empty_list=[] and :value= {
"time": 1485700907669,
"value": 23
}
Break your update expression apart into two separate expressions:
SET #car.#model = if_not_exists(#car.#model, :empty_list) SET #car.#model = list_append(#car.#model, :value)

couchbase sort issue in java code

Below is the document on which I am working:
{
"id": "idgwSRWDUJjQH",
"rev": "15-13d1d4545cd601560000000000000000",
"expiration": 0,
"flags": 0
}
{
"geminiType": "storegroup",
"_class": "web.model.StoreGroup",
"order": "10",
"childId": [
],
"name": "aaa",
"parent": "root",
"userGroupId": [
],
"type": "Folder",
"storeId": [
]
}
I am trying to sort based on name as below
function (doc, meta) {
if(doc.geminiType == "storegroup") {
emit(doc.name, [ meta.id,doc.name, doc.parent, doc.type]);
}
}
This I have created permanent view in couchbase console. I am fetching the document from my jave code using couchbase client as below:
View storeGrpView = cc.getView(RRConsts.STORE_GROUP_VIEW_DESIGN_DOC, RRConsts.STORE_GROUP_VIEW);
Query getAllstoreGrpQuery = new Query();
getAllstoreGrpQuery.setIncludeDocs(true);
getAllstoreGrpQuery.setStale(Stale.FALSE);
ViewResponse result = cc.query(storeGrpView, getAllstoreGrpQuery);
logger.info("getAllstoreGrpQuery resultset: " + result.toString());
for(ViewRow row : result) {
logger.info("store group :"+row.getDocument().toString());
}
}
Here I am getting the result in order of meta.id of the doc but i was expecting the result set to be in order of doc.name. Please let me know where I am doing wrong.
I got the solution to above issue. Actually if I used below two get method instead of row.getDocument() to fetch data, I am getting data in sorted order as expected.
row.getkey()
row.getvalue()