Extjs 5.0 nested association in model causing error = Ext.data.schema.Schema.addEntity(): Duplicate entity name - extjs5

I am having trouble setting the associations with nested references that are reused across different models.
How can do this?
AddressModel
Ext.define('POC.model.AddressModel',
{
extend: 'Ext.data.Model',
fields: [
{ name:'id', type:'string' },
{ name:'line1', type:'string' },
{ name:'line2', type:'string' },
{ name:'city', type:'string' },
{ name:'state', type:'string'},
{ name:'zip', type:'string'}
]
});
Applicant Model
Ext.define('POC.model.ApplicantModel',
{
extend: 'POC.model.Base',
requires: [
"POC.model.field.PhoneNumber",
"POC.model.AddressModel"
],
fields: [
{ name:'id', type:'string' },
{ name:'applicantName', type:'string'},
{ name:'mailingAddress', reference:'AddressModel'}
]
});
Company Model
Ext.define('POC.model.CompanyInfoModel',
{
requires: [
"POC.model.field.PhoneNumber",
"POC.model.AddressModel"
],
extend: 'Ext.data.Model',
fields: [
{ name:'id', type:'string'},
{ name:'contacttype', type:'string' },
{ name:'contactname', type:'string' },
{ name:'primaryphone', type:'phonenumber' },
{ name:'secphone', type:'phonenumber' },
{ name:'primaryemail', type:'string'},
{ name:'secemail', type:'string'},
{ name:'address', reference:'AddressModel'}
]
});
Agent Model
Ext.define('POC.model.AgentInfoModel',
{
extend: 'Ext.data.Model',
requires: [
"POC.model.field.PhoneNumber",
"POC.model.AddressModel"
],
fields: [
{ name:'id', type:'string'},
{ name:'agencyname', type:'string' },
{ name:'contactname', type:'string' },
{ name:'phone', type:'phonenumber' },
{ name:'code', type:'string'},
{ name:'email', type:'string'},
{ name:'address', reference:'AddressModel'}
]
});
Everything comes together in Application Model
Ext.define('POC.model.ApplicationInfoModel',
{
requires:['POC.model.AgentInfoModel',
'POC.model.CompanyInfoModel',
'POC.model.ApplicantModel'
],
extend: 'POC.model.Base',
idProperty:'appid',
fields:[{
name:'appid',type:'string'
},
{
name:'agent',
reference:'AgentInfoModel'
},
{
name:'company',
reference:'CompanyInfoModel'
}
],
hasMany:[{
name:'applicants',
reference:'ApplicantModel'
}]
});
The associated JSON format from the server
{
"success":true,
"application" :
{
"appid":"0",
"company" :
{
"id" : "0",
"contacttype" : "",
"contactname" : "",
"primaryphone" : "",
"secphone" : "",
"primaryemail" : "",
"secemail" : "",
"address" : {
"id":"114444",
"line1" : "",
"line2" : "",
"city" : "",
"state" : "",
"zip" : ""
}
},
"agent" : {
"id" : "0",
"agencyname" : "",
"contactname" : "",
"phone" : "",
"code" : "",
"email" : "",
"address" : {
"id":"11111",
"line1" : "",
"line2" : "",
"city" : "",
"state" : "",
"zip" : ""
}
},
"applicants" :
[{
"id" : "0",
"applicantName" : "",
"mailingAddress" :
{
"id":"1132323",
"line1" : "",
"line2" : "",
"city" : "",
"state" : "",
"zip" : ""
}
}, {
"id" : "1",
"applicantName" : "",
"mailingAddress" :
{
"id":"11323666",
"line1" : "",
"line2" : "",
"city" : "",
"state" : "",
"zip" : ""
}
}
]
}
}
The error that I get...
**W] [Ext.define] Duplicate class name 'POC.model.AddressModel' specified, must be a non- empty string Util.js:692
[E] Ext.data.schema.Schema.addEntity(): Duplicate entity name "AddressModel": POC.model.AddressModel and POC.model.AddressModel
Uncaught Error: Duplicate entity name "AddressModel": POC.model.AddressModel and POC.model.AddressModel**

Solved the issue the ApplicationInfoModel had to be changed like below
Ext.define('POC.model.ApplicationInfoModel',
{
requires:['POC.model.AgentInfoModel',
'POC.model.CompanyInfoModel',
// 'POC.model.ApplicantModel'
],
extend: 'POC.model.Base',
idProperty:'appid',
fields:[{
name:'appid',type:'string'
},
{
name:'agent',
reference:'AgentInfoModel'
},
{
name:'company',
reference:'CompanyInfoModel'
}
],
hasMany:[{
name:'applicants',
model:'POC.model.ApplicantInfoModel',
}]
});

Related

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

Reading complex JSON ARRAY in angular

This is the first time I am working in angular. I am not sure whether this is complex or simple.I want to read the below JSON ARRAY and render it in a complex table.Can some one help me how to read or access the different submodules in it.I can't give exact details like how to render or the table structure as it is too complex to explain rendering this json on table.Can some one just help me how to access different elements of this below JSON ARRAY.
Need to use *ngFor to loop through in my table
Response =
{
"userId" : "",
"module" : "Opportunity",
"moduleDetails" : [
{
"moduleElements" : [
{
"elementName" : "Account Name",
"elementValue" : "155744"
}
{
"elementName" : "oppty owner",
"elementValue" : "Europe"
},
{
"elementName" : "products",
"elementValue" : "June 10,2010"
},
{
"elementName" : "Dom",
"elementValue : "8056568"
},
{
"elementName" : "ASAP ",
"elementValue" : "wer"
},
{
"elementName" : "Price scenario status",
"elementValue" : "$243.00"
}
],
"moduleMilestones" : [
{
"elementName": "statusId",
"elementValue": "60"
},
{
"elementName": "sstId",
"elementValue": "NA"
}
],
"subModules" : [
{
"subModule" : "Solution",
"subModuleDetails" : [
{
"subModuleElements" : [
{
"elementName" : "solutionName",
"elementValue" : "112233"
},
{
"elementName" : "solutionId",
"elementValue" : "SameeraSolution"
},
{
"elementName" : "dealType",
"elementValue" : "AVPN"
},
{
"elementName" : "startDate",
"elementValue" : "28-Jul-1992"
},
{
"elementName" : "endDate",
"elementValue" : "28-Jul-2020"
},
{
"elementName" : "status",
"elementValue" : "Reaeneration"
}
],
"subModuleMilestones" : [
{
"elementName": "statusId",
"elementValue": "60"
},
{
"elementName": "supstId",
"elementValue": "NA"
}
]
},
{
"subModuleElements" : [
{
"elementName" : "soId",
"elementValue" : "332211"
},
{
"elementName" : "same",
"elementValue" : "SameeraSolution"
},
{
"elementName" : "dealType",
"elementValue" : "An"
},
{
"elementName" : "startDate",
"elementValue" : "28-Jul-1992"
},
{
"elementName" : "endDate",
"elementValue" : "28-Jul-2020"
},
{
"elementName" : "status",
"elementValue" : "Reneration"
},
"subModuleMilestones" : [
{
"elementName": "statusId",
"elementValue": "60"
},
{
"elementName": "sustId",
"elementValue": "NA"
}
]
]
}
]
}
]
}
]
}
const theDeets = Response.moduleDetails // accessing object property
const firstDeet = theDeets[0] // accessing array element using index
const secondElementValue = firstDeet[1].elementValue // chaining both methods
console.log(secondElementValue) // prints “Europe”
From here you’ll want to look up Array methods and Object methods to do more stuff with the data, but this is the answer to how you access stuff.

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" }]

How to unwind single document and then process into single result in an array

I have had some great help from #Joao and #Blakes Seven in order to get me as far as I've got. Awesome, thanks guys very much.
What I have a problem with is going from my original simple example and applying it to my real life scenario.
Where I've got to is two separate scripts which work perfectly by themselves but when I try to being the two together, it then only does the first part without applying the second part; it's my lack of experience in Mongo letting me down here.
So, I am able to get a name value pair from the first array set within a document using the following code:
db.raw_originBusinessData.aggregate([
{ "$match": {objectOriginAPI : "Profit & Loss"}}
,{ "$unwind": "$objectRawOriginData.Reports" }
,{ "$unwind": "$objectRawOriginData.Reports.Rows" }
,{ "$unwind": "$objectRawOriginData.Reports.Rows.Rows" }
,{ "$group": {"_id": "$_id","first": { "$first": "$objectRawOriginData.Reports.Rows.Rows.Cells.Value" }
, "temp": { "$push": "$objectRawOriginData.Reports.Rows.Rows.Cells.Value" }
}},
{ "$unwind": "$temp" }
,{"$skip":1}
,{ "$group": {"_id": "$_id", "AccountBalance":{ "$first": "$first" }
}}
])
This gives me the result below, which I'm happy with except for the fact I am not able to name the two values in the Account Balances array.
Mission 1: I want AccountBalance to be an array and the first position has two values: "AccountName" : "Sales", "AccountValue" : 5428.04.
{
"result" : [
{
"_id" : ObjectId("564d12da1506995581569428"),
"AccountBalance" : [
"Sales",
"5428.64"
]
}
],
"ok" : 1.0000000000000000
}
The second part of the problem is that it is only processing one set of values whereas, the document I am processing on has 9 sets to do. I have run the following $unwind on the document and it has perfectly split them into 9 results:
db.raw_originBusinessData.aggregate([
// find document
{ "$match": {objectOriginAPI : "Profit & Loss"}}
// unwind into multiple documents
,{ "$unwind": "$objectRawOriginData.Reports" }
,{ "$unwind": "$objectRawOriginData.Reports.Rows" }
,{ "$unwind": "$objectRawOriginData.Reports.Rows.Rows" }
])
So I get 9 results perfect. Mission 2: What I want to do is to combine this with the script I showed above. I tried the following but it does absolutely no more than the script just above.
db.raw_originBusinessData.aggregate([
// find document
{ "$match": {objectOriginAPI : "Profit & Loss"}}
// unwind into multiple documents
,{ "$unwind": "$objectRawOriginData.Reports" }
,{ "$unwind": "$objectRawOriginData.Reports.Rows" }
,{ "$unwind": "$objectRawOriginData.Reports.Rows.Rows" }
]
// process each document
,{ "$unwind": "$objectRawOriginData.Reports" }
, {"$unwind": "$objectRawOriginData.Reports.Rows" }
, {"$unwind": "$objectRawOriginData.Reports.Rows.Rows" }
, {"$group": {"_id": "$_id","first": { "$first": "$objectRawOriginData.Reports.Rows.Rows.Cells.Value" }
, "a": { "$push": "$objectRawOriginData.Reports.Rows.Rows.Cells.Value" }
}},
{ "$unwind": "$a" }
,{"$skip":1}
,{ "$group": {"_id": "$_id", "AccountBalance":{ "$first": "$first" }
}}
)
Desired Outcome
What I want to get is the following. This is combination of mission 1 and 2.
{
"result" : [
{
"_id" : ObjectId("564d12da1506995581569428"),
"AccountBalance" : [
{"AccountName" : "Sales",
"AccountValue" : "5428.64"},
{"AccountName" : "Total Income",
"AccountValue" : "5428.64"},
{"AccountName" : "Cost of Sales",
"AccountValue" : "100.00"},
{"AccountName" : "Total Cost of Sales",
"AccountValue" : "100.00"},
{"AccountName" : "Gross Profit",
"AccountValue" : "5328.64"},
{"AccountName" : "Advertising",
"AccountValue" : "100.00"},
{"AccountName" : "General Expenses",
"AccountValue" : "100.00"},
{"AccountName" : "Total Operating Expenses",
"AccountValue" : "200.00"},
{"AccountName" : "Net Profit",
"AccountValue" : "5128.64"}
]
}
],
"ok" : 1.0000000000000000
}
The document that I am using as a source is from Xero API - it's one of their reports. It has the same pattern as most reports exported in JSON like Oracle. Below is the actual report so that you have it for reference.
Thanks a million guys, very much appreciated!
{
"_id" : ObjectId("564d12da1506995581569428"),
"objectClass" : "Origin Data",
"objectCategory" : "Application",
"objectType" : "Customer",
"connection_id" : "562033dfca91840cd0c7c54f",
"connectionName" : "Building Accounts",
"entity_id" : "564149bcca9183a8d0c7c83c",
"objectCreationDate" : "2015-11-19 14:43:40",
"objectCycleID" : "12345678",
"objectStatus" : "PROCESSED",
"objectOrigin" : "Xero",
"objectOriginAPI" : "Profit & Loss",
"objectOriginService" : "Xero API - Profit & Loss v 1.0.0.8",
"objectRawOriginData" : {
"Id" : "d6e7fb37-9f2e-45ae-b0a4-de62aa95a783",
"Status" : "OK",
"ProviderName" : "Xero API Previewer",
"DateTimeUTC" : "/Date(1443405874333)/",
"Reports" : [
{
"ReportID" : "ProfitAndLoss",
"ReportName" : "Profit and Loss",
"ReportType" : "ProfitAndLoss",
"ReportTitles" : [
"Profit & Loss",
"Paddy's markets",
"28 September 2014 to 28 September 2015"
],
"ReportDate" : "28 September 2015",
"UpdatedDateUTC" : "/Date(1443405874333)/",
"Fields" : [],
"Rows" : [
{
"RowType" : "Header",
"Cells" : [
{
"Value" : ""
},
{
"Value" : "28 Sep 15"
}
]
},
{
"RowType" : "Section",
"Title" : "Income",
"Rows" : [
{
"RowType" : "Row",
"Cells" : [
{
"Value" : "Sales",
"Attributes" : [
{
"Value" : "a7e3f9e4-6f63-4b25-ae36-107131e8b9be",
"Id" : "account"
}
]
},
{
"Value" : "5428.64",
"Attributes" : [
{
"Value" : "a7e3f9e4-6f63-4b25-ae36-107131e8b9be",
"Id" : "account"
}
]
}
]
},
{
"RowType" : "SummaryRow",
"Cells" : [
{
"Value" : "Total Income"
},
{
"Value" : "5428.64"
}
]
}
]
},
{
"RowType" : "Section",
"Title" : "Less Cost of Sales",
"Rows" : [
{
"RowType" : "Row",
"Cells" : [
{
"Value" : "Cost of Sales",
"Attributes" : [
{
"Value" : "f78f7118-ad98-4862-a63c-39dd3c5ace8a",
"Id" : "account"
}
]
},
{
"Value" : "100.00",
"Attributes" : [
{
"Value" : "f78f7118-ad98-4862-a63c-39dd3c5ace8a",
"Id" : "account"
}
]
}
]
},
{
"RowType" : "SummaryRow",
"Cells" : [
{
"Value" : "Total Cost of Sales"
},
{
"Value" : "100.00"
}
]
}
]
},
{
"RowType" : "Section",
"Title" : "",
"Rows" : [
{
"RowType" : "Row",
"Cells" : [
{
"Value" : "Gross Profit"
},
{
"Value" : "5328.64"
}
]
}
]
},
{
"RowType" : "Section",
"Title" : "Less Operating Expenses",
"Rows" : [
{
"RowType" : "Row",
"Cells" : [
{
"Value" : "Advertising",
"Attributes" : [
{
"Value" : "67466588-132b-48ce-b897-0ceabffd7a9d",
"Id" : "account"
}
]
},
{
"Value" : "100.00",
"Attributes" : [
{
"Value" : "67466588-132b-48ce-b897-0ceabffd7a9d",
"Id" : "account"
}
]
}
]
},
{
"RowType" : "Row",
"Cells" : [
{
"Value" : "General Expenses",
"Attributes" : [
{
"Value" : "fdb25d7a-2fc8-406a-bf4b-6b4e8014b8cb",
"Id" : "account"
}
]
},
{
"Value" : "100.00",
"Attributes" : [
{
"Value" : "fdb25d7a-2fc8-406a-bf4b-6b4e8014b8cb",
"Id" : "account"
}
]
}
]
},
{
"RowType" : "SummaryRow",
"Cells" : [
{
"Value" : "Total Operating Expenses"
},
{
"Value" : "200.00"
}
]
}
]
},
{
"RowType" : "Section",
"Title" : "",
"Rows" : [
{
"RowType" : "Row",
"Cells" : [
{
"Value" : "Net Profit"
},
{
"Value" : "5128.64"
}
]
}
]
}
]
}
]
}
}
done it, see below, thanks:
db.raw_originBusinessData.aggregate([
{ "$match": {objectOriginAPI : "Profit & Loss"}}
,{ "$unwind": "$objectRawOriginData.Reports" }
,{ "$unwind": "$objectRawOriginData.Reports.Rows" }
,{ "$unwind": "$objectRawOriginData.Reports.Rows.Rows" }
,{ "$group": {"_id": "$_id","accountBalances": { "$push": "$objectRawOriginData.Reports.Rows.Rows.Cells.Value" }
}},
])

Mongodb aggregate, match, group and sort on complex JSON

I receive a large amount of JSON back (flight data) which I've been thinking about using mongo as the tool to query/filter it before returning back to the UI.
Here's the json response from Sabre (flight search)
{
"OTA_AirLowFareSearchRS": {
"PricedItineraries": {
"PricedItinerary": [
{
"SequenceNumber": 1,
"AirItinerary": {
"OriginDestinationOptions": {
"OriginDestinationOption": [
{
"FlightSegment": [
{
"DepartureDateTime": "2015-11-12T11:40:00",
"ArrivalDateTime": "2015-11-12T17:35:00",
"FlightNumber": "1980"
},
{
"DepartureDateTime": "2015-11-12T19:35:00",
"ArrivalDateTime": "2015-11-13T02:00:00",
"FlightNumber": "760"
}
]
},
{
"FlightSegment": [
{
"DepartureDateTime": "2015-11-19T08:25:00",
"ArrivalDateTime": "2015-11-19T11:40:00",
"FlightNumber": "763"
},
{
"DepartureDateTime": "2015-11-19T12:55:00",
"ArrivalDateTime": "2015-11-19T15:05:00",
"FlightNumber": "1985"
}
]
}
]
}
},
"AirItineraryPricingInfo": [
{
"ItinTotalFare": {
"TotalFare": {
"Amount": 269.56,
"CurrencyCode": "GBP"
}
}
}
]
},
{
"SequenceNumber": 2,
"AirItinerary": {
"OriginDestinationOptions": {
"OriginDestinationOption": [
{
"FlightSegment": [
{
"DepartureDateTime": "2015-11-12T16:45:00",
"ArrivalDateTime": "2015-11-12T22:40:00",
"FlightNumber": "1986"
},
{
"DepartureDateTime": "2015-11-13T00:40:00",
"ArrivalDateTime": "2015-11-13T07:10:00",
"FlightNumber": "762"
}
]
},
{
"ElapsedTime": 640,
"FlightSegment": [
{
"DepartureDateTime": "2015-11-19T08:25:00",
"ArrivalDateTime": "2015-11-19T11:40:00",
"FlightNumber": "763"
},
{
"DepartureDateTime": "2015-11-19T12:55:00",
"ArrivalDateTime": "2015-11-19T15:05:00",
"FlightNumber": "1985"
}
]
}
]
}
},
"AirItineraryPricingInfo": [
{
"ItinTotalFare": {
"TotalFare": {
"Amount": 269.56,
"CurrencyCode": "GBP"
}
}
}
]
},
{
"SequenceNumber": 6,
"AirItinerary": {
"OriginDestinationOptions": {
"OriginDestinationOption": [
{
"FlightSegment": [
{
"DepartureDateTime": "2015-11-12T11:40:00",
"ArrivalDateTime": "2015-11-12T17:35:00",
"FlightNumber": "1980"
},
{
"DepartureDateTime": "2015-11-12T19:35:00",
"ArrivalDateTime": "2015-11-13T02:00:00",
"FlightNumber": "760"
}
]
},
{
"FlightSegment": [
{
"DepartureDateTime": "2015-11-19T03:15:00",
"ArrivalDateTime": "2015-11-19T06:30:00",
"FlightNumber": "761"
},
{
"DepartureDateTime": "2015-11-19T12:55:00",
"ArrivalDateTime": "2015-11-19T15:05:00",
"FlightNumber": "1985"
}
]
}
]
}
},
"AirItineraryPricingInfo": [
{
"ItinTotalFare": {
"TotalFare": {
"Amount": 269.56
}
}
}
]
}
]
}
}
}
I've been trying to get this into a view that I want but struggling with the complexity of all the nested arrays. My question is how can I achieve a desired result like this:
{
'Price': 269.56, <-- //Group on price (TotalFare)
'Outbound': [{
<Outbound Flights> <--- //$push? flights at array position [0] of OriginDestinationOption
}],
'Inbound': [{
<Inbound Flights> <-- // flights at array position [1] of OriginDestinationOption
}]
},
...
The locations of the data for these in the JSON is:
Price: OTA_AirLowFareSearchRS.PricedItineraries.PricedItinerary[x].AirItineraryPricingInfo[0].ItinTotalFare.TotalFare.Amount;
Inbound: OTA_AirLowFareSearchRS.PricedItineraries.PricedItinerary[x].AirItinerary.OriginDestinationOptions.OriginDestinationOption[0]
Outbound: OTA_AirLowFareSearchRS.PricedItineraries.PricedItinerary[x].AirItinerary.OriginDestinationOptions.OriginDestinationOption[1]
With the current MongoDB release, the only way you can get results which are closer to what you want is by using the aggregation framework, and working on the premise that the OriginDestinationOption array will have two elememts, you'd need the $first and $last operators to select the first and last elements in the array after the $unwind operator. For now (based on the above assumptions) you may have to do with running this pipeline:
db.flights.aggregate([
{ "$unwind": "$OTA_AirLowFareSearchRS.PricedItineraries.PricedItinerary" },
{ "$unwind": "$OTA_AirLowFareSearchRS.PricedItineraries.PricedItinerary.AirItineraryPricingInfo" },
{ "$unwind": "$OTA_AirLowFareSearchRS.PricedItineraries.PricedItinerary.AirItinerary.OriginDestinationOptions.OriginDestinationOption" },
{
"$project": {
"Price": "$OTA_AirLowFareSearchRS.PricedItineraries.PricedItinerary.AirItineraryPricingInfo.ItinTotalFare.TotalFare.Amount",
"DestinationOptions": "$OTA_AirLowFareSearchRS.PricedItineraries.PricedItinerary.AirItinerary.OriginDestinationOptions.OriginDestinationOption"
}
},
{
"$group": {
"_id": "$Price",
"Outbound" : { "$first": "$DestinationOptions" },
"Inbound" : { "$last": "$DestinationOptions" }
}
}
])
which will yield the result (from the sample data):
/* 1 */
{
"result" : [
{
"_id" : 269.56,
"Outbound" : {
"ElapsedTime" : 620,
"FlightSegment" : [
{
"DepartureDateTime" : "2015-11-12T11:40:00",
"ArrivalDateTime" : "2015-11-12T17:35:00",
"StopQuantity" : 0,
"FlightNumber" : "1980",
"ElapsedTime" : 235,
"DepartureAirport" : {
"LocationCode" : "LHR",
"TerminalID" : "2",
"content" : ""
},
"ArrivalAirport" : {
"LocationCode" : "IST",
"TerminalID" : "I",
"content" : ""
},
"OperatingAirline" : {
"Code" : "TK",
"FlightNumber" : "1980",
"content" : ""
}
},
{
"DepartureDateTime" : "2015-11-12T19:35:00",
"ArrivalDateTime" : "2015-11-13T02:00:00",
"StopQuantity" : 0,
"FlightNumber" : "760",
"ResBookDesigCode" : "W",
"ElapsedTime" : 265,
"DepartureAirport" : {
"LocationCode" : "IST",
"TerminalID" : "I",
"content" : ""
},
"ArrivalAirport" : {
"LocationCode" : "DXB",
"TerminalID" : "1",
"content" : ""
},
"OperatingAirline" : {
"Code" : "TK",
"FlightNumber" : "760",
"content" : ""
},
"Equipment" : [
{
"AirEquipType" : "343",
"content" : ""
}
],
"MarketingAirline" : {
"Code" : "TK",
"content" : ""
},
"MarriageGrp" : "I",
"DepartureTimeZone" : {
"GMTOffset" : 2
},
"ArrivalTimeZone" : {
"GMTOffset" : 4
},
"TPA_Extensions" : {
"eTicket" : {
"Ind" : true
}
}
}
]
},
"Inbound" : {
"ElapsedTime" : 730,
"FlightSegment" : [
{
"DepartureDateTime" : "2015-11-19T08:25:00",
"ArrivalDateTime" : "2015-11-19T11:40:00",
"StopQuantity" : 0,
"FlightNumber" : "763",
"ResBookDesigCode" : "W",
"ElapsedTime" : 315,
"DepartureAirport" : {
"LocationCode" : "DXB",
"TerminalID" : "1",
"content" : ""
},
"ArrivalAirport" : {
"LocationCode" : "IST",
"TerminalID" : "I",
"content" : ""
},
"OperatingAirline" : {
"Code" : "TK",
"FlightNumber" : "763",
"content" : ""
},
"Equipment" : [
{
"AirEquipType" : "330",
"content" : ""
}
],
"MarketingAirline" : {
"Code" : "TK",
"content" : ""
},
"MarriageGrp" : "O",
"DepartureTimeZone" : {
"GMTOffset" : 4
},
"ArrivalTimeZone" : {
"GMTOffset" : 2
},
"TPA_Extensions" : {
"eTicket" : {
"Ind" : true
}
}
},
{
"DepartureDateTime" : "2015-11-19T14:25:00",
"ArrivalDateTime" : "2015-11-19T16:35:00",
"StopQuantity" : 0,
"FlightNumber" : "1971",
"ResBookDesigCode" : "W",
"ElapsedTime" : 250,
"DepartureAirport" : {
"LocationCode" : "IST",
"TerminalID" : "I",
"content" : ""
},
"ArrivalAirport" : {
"LocationCode" : "LHR",
"TerminalID" : "2",
"content" : ""
},
"OperatingAirline" : {
"Code" : "TK",
"FlightNumber" : "1971",
"content" : ""
},
"Equipment" : [
{
"AirEquipType" : "32B",
"content" : ""
}
],
"MarketingAirline" : {
"Code" : "TK",
"content" : ""
},
"MarriageGrp" : "I",
"DepartureTimeZone" : {
"GMTOffset" : 2
},
"ArrivalTimeZone" : {
"GMTOffset" : 0
},
"TPA_Extensions" : {
"eTicket" : {
"Ind" : true
}
}
}
]
}
}
],
"ok" : 1
}
However, with the future releases (MongoDB 3.2 and newer), there are two operators $slice and $arrayElemAt which will work for you to produce the desired result. The $slice operator returns a subset of an array and the $arrayElemAt returns the element at the specified array index.
Thus you will implement the pipeline as follows -
Case 1. Using the $slice operator:
db.flights.aggregate([
{ "$unwind": "$OTA_AirLowFareSearchRS.PricedItineraries.PricedItinerary" },
{ "$unwind": "$OTA_AirLowFareSearchRS.PricedItineraries.PricedItinerary.AirItineraryPricingInfo" },
{ "$unwind": "$OTA_AirLowFareSearchRS.PricedItineraries.PricedItinerary.AirItinerary.OriginDestinationOptions.OriginDestinationOption" },
{
"$project": {
"Price": "$OTA_AirLowFareSearchRS.PricedItineraries.PricedItinerary.AirItineraryPricingInfo.ItinTotalFare.TotalFare.Amount",
"DestinationOptions": "$OTA_AirLowFareSearchRS.PricedItineraries.PricedItinerary.AirItinerary.OriginDestinationOptions.OriginDestinationOption"
}
},
{
"$group": {
"_id": "$Price",
"DestinationOptions" : { "$push": "$DestinationOptions" }
}
},
{
"$project": {
"Inbound": { "$slice": [ "$DestinationOptions", 0, 1] },
"Outbound": { "$slice": [ "$DestinationOptions", 1, 1 ] },
"Price": "$_id",
"_id": 0
}
}
])
Case 2. Using the $arrayElemAt operator:
db.flights.aggregate([
{ "$unwind": "$OTA_AirLowFareSearchRS.PricedItineraries.PricedItinerary" },
{ "$unwind": "$OTA_AirLowFareSearchRS.PricedItineraries.PricedItinerary.AirItineraryPricingInfo" },
{ "$unwind": "$OTA_AirLowFareSearchRS.PricedItineraries.PricedItinerary.AirItinerary.OriginDestinationOptions.OriginDestinationOption" },
{
"$project": {
"Price": "$OTA_AirLowFareSearchRS.PricedItineraries.PricedItinerary.AirItineraryPricingInfo.ItinTotalFare.TotalFare.Amount",
"DestinationOptions": "$OTA_AirLowFareSearchRS.PricedItineraries.PricedItinerary.AirItinerary.OriginDestinationOptions.OriginDestinationOption"
}
},
{
"$group": {
"_id": "$Price",
"DestinationOptions" : { "$push": "$DestinationOptions" }
}
},
{
"$project": {
"Inbound": { "$arrayElemAt": [ "$DestinationOptions", 0] },
"Outbound": { "$arrayElemAt": [ "$DestinationOptions", 1 ] },
"Price": "$_id",
"_id": 0
}
}
])