Adding an hardcoded property to a json output - json

Here is my code in mongodb : .
db.mydb.aggregate([
{ "$group": {
"_id": {
"A": "$A",
"B": "$B",
"C": "$C"
},
}},
{ "$group": {
"cpt": { '$sum': 1 } ,
"_id": "$_id.A",
"allowDrag": {'$literal':false},
"expanded": {'$literal':false},
"children": {
"$push": {
"text": "$_id.B",
"details": "$_id.C",
"leaf": {'$literal': true},
}
},
}}
])
I would like to add in my json output some hardcoded properties and values, it works with
"leaf": {'$literal': true}
but I don't know why I can't make it with
"allowDrag": {'$literal':false},
"expanded": {'$literal':false}
is it possible with $group?
Example of the output json I've got :
"result" : [
{
"_id" : "A",
"cpt" : 1,
"children" : [
{
"text" : "B",
"details" : "C",
"leaf" : true
}
]
}]
Example of the output json I wish I had :
"result" : [
{
"_id" : "A",
"cpt" : 1,
"allowDrag" : false,
"expanded" : false,
"children" : [
{
"text" : "B",
"details" : "C",
"leaf" : true
}
]
}]

Use the $literal operator in the $project pipeline to return the new fields set to boolean values of false:
db.mydb.aggregate([
{
"$group": {
"_id": {
"A": "$A",
"B": "$B",
"C": "$C"
}
}
},
{
"$group": {
"cpt": { '$sum': 1 } ,
"_id": "$_id.A",
"children": {
"$push": {
"text": "$_id.B",
"details": "$_id.C",
"leaf": {'$literal': true}
}
}
}
},
{
"$project": {
"allowDrag": {'$literal':false},
"expanded": {'$literal':false},
"cpt": 1,
"children": 1
}
}
])
Tested with the following collection sample:
db.mydb.insert([
{
"A": "test1",
"B": "test2",
"C": "test3"
},
{
"A": "test1",
"B": "test2",
"C": "test2"
},
{
"A": "test2",
"B": "test2",
"C": "test3"
},
{
"A": "test2",
"B": "test2",
"C": "test3"
}
])
The above aggregation gives the following results:
/* 0 */
{
"result" : [
{
"_id" : "test1",
"cpt" : 2,
"children" : [
{
"text" : "test2",
"details" : "test2",
"leaf" : true
},
{
"text" : "test2",
"details" : "test3",
"leaf" : true
}
],
"allowDrag" : false,
"expanded" : false
},
{
"_id" : "test2",
"cpt" : 1,
"children" : [
{
"text" : "test2",
"details" : "test3",
"leaf" : true
}
],
"allowDrag" : false,
"expanded" : false
}
],
"ok" : 1
}

Related

Jsonpath: get the list of elements that contain at least one id from a list of ids

With the following json:
{
"elements": [
{
"ids": [
{
"id": "A"
},
{
"id": "B"
}
],
"value": "one"
},
{
"ids": [
{
"id": "C"
},
{
"id": "D"
}
],
"value": "two"
},
{
"ids": [
{
"id": "E",
},
{
"id": "F",
}
],
"value": "three"
}
]
}
What would be the jsonpath to return the list of the elements containing at least an id from the list ['A','C']?
I can get the desired result if I ask specifically for each id:
$.elements[?('A' in #.ids.*.id || 'C' in #.ids.*.id)]
[
{
"ids" : [
{
"id" : "A"
},
{
"id" : "B"
}
],
"value" : "one"
},
{
"ids" : [
{
"id" : "C"
},
{
"id" : "D"
}
],
"value" : "two"
}
]
but in my scenario I need to indicate the values of the ids within a list ['A','C']
Thanks in advance!
use the anyof filter operator
$.elements[?(#.ids.*.id anyof ['A','C'])]

NiFi, Jolt's operation "substring" doesn't work

I have some datetime marks, and what I pretend is to group it in the quarter of hour just before it.
I have, e.g., this data:
[
{
"id": "123",
"dateTime": "2020-07-08T08:49:50+02:00",
"value": "1"
},
{
"id": "123",
"dateTime": "2020-07-08T13:14:57+02:00",
"value": "1"
},
{
"id": "123",
"dateTime": "2020-07-08T13:15:15+02:00",
"value": "1"
},
{
"id": "123",
"dateTime": "2020-07-08T13:36:39+02:00",
"value": "1"
}
]
After some JOLT Transformations, I have this data:
[ {
"id" : "123",
"dateHour" : "2020-07-08T08",
"minutes" : "45",
"value" : "1"
}, {
"id" : "123",
"dateHour" : "2020-07-08T13",
"minutes" : "0",
"value" : "1"
}, {
"id" : "123",
"dateHour" : "2020-07-08T13",
"minutes" : "15",
"value" : "1"
}, {
"id" : "123",
"dateHour" : "2020-07-08T13",
"minutes" : "30",
"value" : "1"
} ]
here, I have a problem. With the webpage http://jolt-demo.appspot.com/, I have managed to convert that "0" in "00" with the following JOLT code
[
{ "operation": "modify-overwrite-beta",
"spec": {
"*": {
"minutes": "=concat('0',#(0))"
}
}
},
{ "operation": "modify-overwrite-beta",
"spec": {
"*": {
"minutes": "=substring(#(1,minutes),1,3)"
}
}
}
]
Expected output (and achived with the webpage):
[ {
"id" : "123",
"dateHour" : "2020-07-08T08",
"minutes" : "45",
"value" : "1"
}, {
"id" : "123",
"dateHour" : "2020-07-08T13",
"minutes" : "00",
"value" : "1"
}, {
"id" : "123",
"dateHour" : "2020-07-08T13",
"minutes" : "15",
"value" : "1"
}, {
"id" : "123",
"dateHour" : "2020-07-08T13",
"minutes" : "30",
"value" : "1"
} ]
Real output in NiFi:
[ {
"id" : "123",
"dateHour" : "2020-07-08T08",
"minutes" : "045",
"value" : "1"
}, {
"id" : "123",
"dateHour" : "2020-07-08T13",
"minutes" : "00",
"value" : "1"
}, {
"id" : "123",
"dateHour" : "2020-07-08T13",
"minutes" : "015",
"value" : "1"
}, {
"id" : "123",
"dateHour" : "2020-07-08T13",
"minutes" : "030",
"value" : "1"
} ]
For some reason, "=substring()" function doesn't work as I expected in NiFi. Does anyone have any knack to take the last 2 items of the string?
You can convert to number and leftPad it. See if it helps
[
{
"operation": "modify-overwrite-beta",
"spec": {
"*": {
"minutes": ["=toInteger", 0]
}
}
},
{
"operation": "modify-overwrite-beta",
"spec": {
"*": {
"minutes": "=toString"
}
}
},
{
"operation": "modify-overwrite-beta",
"spec": {
"*": {
"minutes": "=leftPad(#(1,minutes),2,'0')"
}
}
}
]
Input:
[
{
"id": "123",
"dateHour": "2020-07-08T08",
"minutes": "045",
"value": "1"
},
{
"id": "123",
"dateHour": "2020-07-08T13",
"minutes": "00",
"value": "1"
},
{
"id": "123",
"dateHour": "2020-07-08T13",
"minutes": "015",
"value": "1"
},
{
"id": "123",
"dateHour": "2020-07-08T13",
"minutes": "030",
"value": "1"
}
]
output:
[ {
"id" : "123",
"dateHour" : "2020-07-08T08",
"minutes" : "45",
"value" : "1"
}, {
"id" : "123",
"dateHour" : "2020-07-08T13",
"minutes" : "00",
"value" : "1"
}, {
"id" : "123",
"dateHour" : "2020-07-08T13",
"minutes" : "15",
"value" : "1"
}, {
"id" : "123",
"dateHour" : "2020-07-08T13",
"minutes" : "30",
"value" : "1"
} ]

Query with aggregate, lookup and pipeline in Mongodb

I have to manage a wall with comments, each wall have many parent comments and each parent comment have child comments.
my collection walls is like this
groupId : {type: Schema.Types.ObjectId, ref: 'groups', unique: true},
comments : [{
commentId : {type: Schema.Types.ObjectId, ref: 'comments'},
user : {type: Schema.Types.ObjectId, ref: 'users'},
}],
and the collection comments is like this
text : String,
parentCommentId : {type: Schema.Types.ObjectId, ref: 'comments', default : null},
I want to display my wall by parent comments, each child comment under its parent comment.
i tried this query but it didn't return any results
db.getCollection('walls').aggregate([
{$match: {groupId: ObjectId("5e8c5caa75b1cd342a1175eb")}},
{
"$lookup": {
from: "comments",
let: { item: "$comments.commentId" },
pipeline: [
{ $match:
{ $expr: { $eq: [ "$parentCommentId", "$$item" ] }
}
},
{ $project: {
"_id": 1,
"parentCommentId": 1,
"text": 1
} }
],
as: "comments"
}
},
{
$project: {
groupId: 1,
"comments":1,
date: 1
}
}
])
data in walls
{
"_id" : ObjectId("5e95b4b49d3e303d667a8b71"),
"groupId" : ObjectId("5e8c5caa75b1cd342a1175eb"),
"comments" : [
{
"_id" : ObjectId("5e95b4b49d3e303d667a8b72"),
"commentId" : ObjectId("5e95b4b49d3e303d667a8b70")
},
{
"_id" : ObjectId("5e95b4ef80ae1244693aa857"),
"commentId" : ObjectId("5e95b4ef80ae1244693aa856")
},
{
"_id" : ObjectId("5e95b51080ae1244693aa859"),
"commentId" : ObjectId("5e95b51080ae1244693aa858")
},
{
"_id" : ObjectId("5e95b51d80ae1244693aa85b"),
"commentId" : ObjectId("5e95b51d80ae1244693aa85a")
},
{
"_id" : ObjectId("5e95b53580ae1244693aa85e"),
"commentId" : ObjectId("5e95b53580ae1244693aa85c")
}
],
}
data in comments
{
"_id" : ObjectId("5e95b4b49d3e303d667a8b70"),
"parentCommentId" : null,
"text" : "Hello parent 1"
}
{
"_id" : ObjectId("5e95b4ef80ae1244693aa856"),
"parentCommentId" : null,
"text" : "Hello parent 2",
"date" : ISODate("2020-04-14T13:04:47.860Z")
}
{
"_id" : ObjectId("5e95b51080ae1244693aa858"),
"parentCommentId" : ObjectId("5e95b4b49d3e303d667a8b70"),
"text" : "Hello child 1 parent 1"
}
{
"_id" : ObjectId("5e95b51d80ae1244693aa85a"),
"parentCommentId" : ObjectId("5e95b4b49d3e303d667a8b70"),
"text" : "Hello child 2 parent 1"
}
{
"_id": "5e95b53580ae1244693aa85c",
"parentCommentId": "5e95b4ef80ae1244693aa856",
"text": "Hello child 1 parent 2",
}
desired result
{
"success": true,
"data": [
{
"_id": "5e95b4b49d3e303d667a8b71",
"groupId": "5e8c5caa75b1cd342a1175eb",
"comments": [
{
"_id": "5e95b4b49d3e303d667a8b70",
"parentCommentId": null,
"text": "Hello parent 1",
"childs": {
{
"_id": "5e95b51080ae1244693aa858",
"parentCommentId": "5e95b4b49d3e303d667a8b70",
"text": "Hello child 1 parent 1",
},
{
"_id": "5e95b51d80ae1244693aa85a",
"parentCommentId": "5e95b4b49d3e303d667a8b70",
"text": "Hello child 2 parent 1",
},
}
},
{
"_id": "5e95b4ef80ae1244693aa856",
"parentCommentId": null,
"text": "Hello parent 2",
"childs": {
{
"_id": "5e95b53580ae1244693aa85c",
"parentCommentId": "5e95b4ef80ae1244693aa856",
"text": "Hello child 1 parent 2",
}
}
},
],
}
]
}
How can i modify my query ? thank you.
You can use below aggregation
db.walls.aggregate([
{ "$lookup": {
"from": "comments",
"let": { "commentIds": "$comments.commentId" },
"pipeline": [
{ "$match": {
"$expr": { "$in": ["$_id", "$$commentIds"] },
"parentCommentId": null
}},
{ "$sort": { "text": -1 }},
{ "$graphLookup": {
"from": "comments",
"startWith": "$_id",
"connectFromField": "parentCommentId",
"connectToField": "parentCommentId",
"as": "childs"
}}
],
"as": "comments"
}}
])
MongoPlayground

Cloudformation in create stack error: "ELB cannot be attached to multiple subnets in the same AZ"

I trying to build infrastracture with Cloudformation json template. When I added two Subnets and SubnetRouteTableAssociation in both availability zones that i need. But creating process failing to create Loadbalancers with error:
CREATE_FAILED AWS::ElasticLoadBalancing::LoadBalancer Rest ELB cannot
be attached to multiple subnets in the same AZ.
Here is the Parameters of AZs:
"AZs" : {
"Description" : "The list of AvailabilityZones.",
"Type" : "CommaDelimitedList",
"Default" : "us-east-1a,us-east-1c"
}
Here is Resources of Subnets, SubnetRouteTableAssociation in both availability zones and ElasticLoadBalancing of Rest:
"PublicSubnet1a" : {
"Type" : "AWS::EC2::Subnet",
"Properties" : {
"VpcId" : { "Ref" : "VPC" },
"CidrBlock" : "10.0.0.0/24",
"AvailabilityZone": {
"Fn::Select": ["1", { "Ref": "AZs" }]
},
"Tags" : [
{"Key": "Name", "Value": {"Fn::Join": ["", ["Offering-", {"Ref": "Env"}, {"Ref": "EnvNum"}, "-VPC"]]}},
{"Key" : "Network", "Value" : "Public" }
]
}
},
"PublicSubnet1c" : {
"Type": "AWS::EC2::Subnet",
"Properties": {
"VpcId": { "Ref" : "VPC" },
"CidrBlock": "10.0.1.0/24",
"AvailabilityZone": {
"Fn::Select": ["1", { "Ref": "AZs" }]
},
"Tags" : [
{"Key": "Name", "Value": {"Fn::Join": ["", ["Offering-", {"Ref": "Env"}, {"Ref": "EnvNum"}, "-VPC"]]}},
{"Key" : "Network", "Value" : "Public" }
]
}
},
"PublicSubnet1aRouteTableAssociation" : {
"Type" : "AWS::EC2::SubnetRouteTableAssociation",
"Properties" : {
"SubnetId" : { "Ref" : "PublicSubnet1a" },
"RouteTableId" : { "Ref" : "PublicRouteTable" }
}
},
"PublicSubnet1cRouteTableAssociation" : {
"Type" : "AWS::EC2::SubnetRouteTableAssociation",
"Properties" : {
"SubnetId" : { "Ref" : "PublicSubnet1c" },
"RouteTableId" : { "Ref" : "PublicRouteTable" }
}
},
"RestELB" : {
"Type" : "AWS::ElasticLoadBalancing::LoadBalancer",
"DependsOn": "AttachGateway",
"Properties": {
"LoadBalancerName": {"Fn::Join": ["",["Rest-ELB-", {"Ref": "VPC"}]]},
"CrossZone" : "true",
"Subnets": [{ "Ref": "PublicSubnet1a" },{ "Ref": "PublicSubnet1c" }],
"Listeners" : [
{"LoadBalancerPort" : "80", "InstancePort" : "80","Protocol" : "HTTP"},
{"LoadBalancerPort" : "6060", "InstancePort" : "6060","Protocol" : "HTTP"}
],
"HealthCheck" : {
"Target" : "HTTP:80/",
"HealthyThreshold" : "3",
"UnhealthyThreshold" : "5",
"Interval" : "90",
"Timeout" : "60"
}
}
}
What I'm doing wrong?
Thanks!
"PublicSubnet1a" : {
...
"AvailabilityZone": {
"Fn::Select": ["1", { "Ref": "AZs" }] // <---- selects index 1 from AZs list
},
...
"PublicSubnet1c" : {
...
"AvailabilityZone": {
"Fn::Select": ["1", { "Ref": "AZs" }] // <---- selects the same index 1 from AZs list
},
both of your subnets are selecting the same index from AZs list (see "FN::select" statement). Change the select statement for PublicSubnet1a to be
"Fn::Select": ["0", { "Ref": "AZs" }]

Groovy: Convert Array to JSon

Am new to Groovy and am having trouble converting an array to JSON. The JSON computed should have all the values from my array list, but it is storing only the last one. Here is the code:
def arraylist = [["0",2],["1",8],["2",6],["3",8],["4",3]]
def arraysize = arraylist.size()
def builder = new groovy.json.JsonBuilder()
builder ({
cols([
{
"id" "hours"
"label" "Hours"
"type" "string"
},
{
"id" "visitor"
"label" "Visitors"
"type" "number"
}
])
rows([
{
for( i in 0..< arraysize )
{
c([
{
"v" arraylist[i][0]
},
{
"v" arraylist[i][1]
}
])
}//for
}
])
})
println builder.toPrettyString()
Can try running the code here:
http://groovyconsole.appspot.com/
Expected output is here:
{
"cols": [
{
"id": "hours",
"label": "Hours",
"type": "string"
},
{
"id": "visitor",
"label": "Visitors",
"type": "number"
}
],
"rows": [
{
"c": [
{
"v": "0"
},
{
"v": 2
}
]
},
{
"c": [
{
"v": "1"
},
{
"v": 8
}
]
},
{
"c": [
{
"v": "2"
},
{
"v": 6
}
]
},
{
"c": [
{
"v": "3"
},
{
"v": 8
}
]
},
{
"c": [
{
"v": "4"
},
{
"v": 3
}
]
}
]
}
Something like this seems to give the result you wanted:
def arraylist = [["0",2],["1",8],["2",6],["3",8],["4",3]]
def builder = new groovy.json.JsonBuilder()
builder {
cols( [
[ id: "hours", label: "Hours", type: "string" ],
[ id: "visitor", label: "Visitors", type: "number" ] ] )
rows( arraylist.collect { pair -> [ c: pair.collect { item -> [ v: item ] } ] } )
}
println builder.toPrettyString()