how to solve this error in mongodb aggregation: TypeError: ({$unwind:{path:"$tags", preserveNullAndEmptyArrays:true}}) is not iterable : - mongodb-query

i have a collection
[{
"_id": {"$oid": "63873b95c7e956270e734f3c"},
"employeeId": "emp1",
"users": [{"name": "Allen","registered": true},
{"name": "Henry","registered": true},
{"name": "Adam","registered": false}],
"tags": ["good","excellent","average"]
},{
"_id": {"$oid": "63873c05c7e956270e734f3d"},
"employeeId": "emp2",
"users": [{"name": "Federick","registered": false},
{"name": "Mary","registered": true},
{"name": "Sam","registered": false} ],
"tags": ["poor","excellent", "good"]}
,{
"_id": {"$oid": "63873c1fc7e956270e734f3e"},
"employeeId": "emp3",
"users": [ {"name": "john", "registered": true},
{"name": "jack","registered": true},
{"name": "elle", "registered": false } ],
"tags": ["very good", "excellent", "good" ]}]
i am trying to groupby tags and employee with count of employees under each tag,expected output is
i am getting the correct output by python code which is
pipeline = [{"$unwind":"$users"},{"$match":{"users.registered":True}},
{"$unwind":"$tags"},
{
"$group": {
"_id": "$tags","employees":{"$push": {"employeeId":"$employeeId"}},
"employees" : { "$addToSet" : "$employeeId" },
"count": {
"$sum": 1
}
}
},
{"$project":{"_id":1,"employees":1,"size":{"$size":"$employees"}}},
{"$sort" : { "size": -1 } },
]
rec = db.ratings.aggregate(pipeline)
but its giving error in mongoshell

Is this what you want?
db.collection.aggregate([
{
"$unwind": "$tags"
},
{
"$group": {
"_id": "$tags",
"employees": {
"$push": "$employeeId"
}
}
},
{
"$project": {
"_id": 1,
"employees": 1,
"size": {
"$size": "$employees"
}
}
},
{
"$sort": {
"size": -1
}
}
])
See how it works on the playground example

Related

Shopware 6 API / Product Listing / How to add available color variants for each product on the response

API Request
/store-api/product-listing/{categoryId}
I want each product in the API response to have available color variants. Because I want to show color variants on the product list page. But currently this data is not provided by the shopware 6 api.
I've tried to add this data by using associations but it didnt help.
Request Body
{
"includes": {
"product": ["id", "productNumber", "cover", "options"]
},
"associations": {
"options": {
"media": []
}
}
}
The request body looks to be correct. If the product is a variant then it should have content for options.
To verify try the following request body:
{
"limit": 1,
"includes": {
"product": ["id", "productNumber", "options"],
"property_group_option": ["name", "group"],
"property_group": ["name"]
},
"associations": {
"options": {
"associations": {
"group": []
}
}
},
"filters": [
{
"type": "not",
"operator": "and",
"queries": [
{
"type": "equals",
"field": "parentId",
"value": null
}
]
}
]
}
This should yield a single variant.
Response should look similar to this:
{
"entity": "product",
"total": 1,
"aggregations": [],
"page": 1,
"limit": 1,
"elements": [
{
"productNumber": "10042.1",
"options": [
{
"name": "linen",
"group": {
"name": "textile",
"apiAlias": "property_group"
},
"apiAlias": "property_group_option"
},
{
"name": "35",
"group": {
"name": "size",
"apiAlias": "property_group"
},
"apiAlias": "property_group_option"
},
{
"name": "chartreuse",
"group": {
"name": "shirt-color",
"apiAlias": "property_group"
},
"apiAlias": "property_group_option"
}
],
"id": "0002ea44c49c41ecb91c43e7e49e422d",
"apiAlias": "product"
}
],
"states": [],
"apiAlias": "dal_entity_search_result"
}

I keep getting 400 error(travelerId not existing) on calling the CreateOrder API

I am on a test Account.
On printing the travelerPricings Object to console, I have this
[
{
travelerId: '1',
fareOption: 'STANDARD',
travelerType: 'ADULT',
price: {
currency: '',
total: '',
base: '',
taxes: [Array],
refundableTaxes: ''
},
fareDetailsBySegment: [ [Object], [Object], [Object], [Object] ]
},
{
travelerId: '2',
fareOption: 'STANDARD',
travelerType: 'CHILD',
price: {
currency: '',
total: '',
base: '',
taxes: [Array],
refundableTaxes: ''
},
fareDetailsBySegment: [ [Object], [Object], [Object], [Object] ]
}
]
Yet on the Api Response, I keep getting the error pointer as
/data/flightOffers[0]/travelerPricings[1]"
Which is not true. As seen in the log shared above,
travelerPricings[1].travelerId = '2'
Please Why could this error come up? Thanks
Based on the Request, Here is the sample payload
{"data":
{
"flightOffers": [
{
"type": "flight-offer",
"id": "1",
"source": "GDS",
"instantTicketingRequired": false,
"nonHomogeneous": false,
"paymentCardRequired": false,
"lastTicketingDate": "2022-08-01",
"itineraries": [
{
"segments": [
{
"departure": {
"iataCode": "SYD",
"terminal": "1",
"at": "2022-08-01T11:35:00"
},
"arrival": {
"iataCode": "MNL",
"terminal": "2",
"at": "2022-08-01T16:50:00"
},
"carrierCode": "PR",
"number": "212",
"aircraft": {
"code": "333"
},
"operating": {
"carrierCode": "PR"
},
"duration": "PT7H15M",
"id": "15",
"numberOfStops": 0,
"co2Emissions": [
{
"weight": 716,
"weightUnit": "KG",
"cabin": "BUSINESS"
}
]
},
{
"departure": {
"iataCode": "MNL",
"terminal": "1",
"at": "2022-08-01T19:20:00"
},
"arrival": {
"iataCode": "BKK",
"at": "2022-08-01T21:50:00"
},
"carrierCode": "PR",
"number": "732",
"aircraft": {
"code": "320"
},
"operating": {
"carrierCode": "PR"
},
"duration": "PT3H30M",
"id": "16",
"numberOfStops": 0,
"co2Emissions": [
{
"weight": 148,
"weightUnit": "KG",
"cabin": "BUSINESS"
}
]
}
]
},
{
"segments": [
{
"departure": {
"iataCode": "BKK",
"at": "2022-08-05T22:50:00"
},
"arrival": {
"iataCode": "MNL",
"terminal": "2",
"at": "2022-08-06T03:15:00"
},
"carrierCode": "PR",
"number": "733",
"aircraft": {
"code": "321"
},
"operating": {
"carrierCode": "PR"
},
"duration": "PT3H25M",
"id": "59",
"numberOfStops": 0,
"co2Emissions": [
{
"weight": 148,
"weightUnit": "KG",
"cabin": "ECONOMY"
}
]
},
{
"departure": {
"iataCode": "MNL",
"terminal": "1",
"at": "2022-08-06T22:10:00"
},
"arrival": {
"iataCode": "SYD",
"terminal": "1",
"at": "2022-08-07T09:45:00"
},
"carrierCode": "PR",
"number": "211",
"aircraft": {
"code": "333"
},
"operating": {
"carrierCode": "PR"
},
"duration": "PT9H35M",
"id": "60",
"numberOfStops": 0,
"co2Emissions": [
{
"weight": 358,
"weightUnit": "KG",
"cabin": "ECONOMY"
}
]
}
]
}
],
"price": {
"currency": "NGN",
"total": "1479460.00",
"base": "1298255.00",
"fees": [
{
"amount": "0.00",
"type": "SUPPLIER"
},
{
"amount": "0.00",
"type": "TICKETING"
},
{
"amount": "0.00",
"type": "FORM_OF_PAYMENT"
}
],
"grandTotal": "1479460.00",
"billingCurrency": "NGN"
},
"pricingOptions": {
"fareType": [
"PUBLISHED"
],
"includedCheckedBagsOnly": false
},
"validatingAirlineCodes": [
"PR"
],
"travelerPricings": [
{
"travelerId": "1",
"fareOption": "STANDARD",
"travelerType": "ADULT",
"price": {
"currency": "NGN",
"total": "840536",
"base": "740769",
"taxes": [
{
"amount": "384.00",
"code": "G8"
},
{
"amount": "19112.00",
"code": "WY"
},
{
"amount": "896.00",
"code": "E7"
},
{
"amount": "18329.00",
"code": "AU"
},
{
"amount": "42766.00",
"code": "YQ"
},
{
"amount": "9320.00",
"code": "LI"
},
{
"amount": "8960.00",
"code": "TS"
}
],
"refundableTaxes": "108123"
},
"fareDetailsBySegment": [
{
"segmentId": "15",
"cabin": "BUSINESS",
"fareBasis": "DBAU",
"class": "D",
"includedCheckedBags": {
"weight": 40,
"weightUnit": "KG"
}
},
{
"segmentId": "16",
"cabin": "BUSINESS",
"fareBasis": "DBAU",
"class": "D",
"includedCheckedBags": {
"weight": 40,
"weightUnit": "KG"
}
},
{
"segmentId": "59",
"cabin": "ECONOMY",
"fareBasis": "KBAU",
"class": "K",
"includedCheckedBags": {
"weight": 30,
"weightUnit": "KG"
}
},
{
"segmentId": "60",
"cabin": "ECONOMY",
"fareBasis": "KBAU",
"class": "K",
"includedCheckedBags": {
"weight": 30,
"weightUnit": "KG"
}
}
]
},
{
"travelerId": "2",
"fareOption": "STANDARD",
"travelerType": "CHILD",
"price": {
"currency": "NGN",
"total": "638924",
"base": "557486",
"taxes": [
{
"amount": "384.00",
"code": "G8"
},
{
"amount": "19112.00",
"code": "WY"
},
{
"amount": "896.00",
"code": "E7"
},
{
"amount": "42766.00",
"code": "YQ"
},
{
"amount": "9320.00",
"code": "LI"
},
{
"amount": "8960.00",
"code": "TS"
}
],
"refundableTaxes": "89794"
},
"fareDetailsBySegment": [
{
"segmentId": "15",
"cabin": "BUSINESS",
"fareBasis": "DBAU",
"class": "D",
"includedCheckedBags": {
"weight": 40,
"weightUnit": "KG"
}
},
{
"segmentId": "16",
"cabin": "BUSINESS",
"fareBasis": "DBAU",
"class": "D",
"includedCheckedBags": {
"weight": 40,
"weightUnit": "KG"
}
},
{
"segmentId": "59",
"cabin": "ECONOMY",
"fareBasis": "KBAU",
"class": "K",
"includedCheckedBags": {
"weight": 30,
"weightUnit": "KG"
}
},
{
"segmentId": "60",
"cabin": "ECONOMY",
"fareBasis": "KBAU",
"class": "K",
"includedCheckedBags": {
"weight": 30,
"weightUnit": "KG"
}
}
]
}
]
}
],
"travelers": [ {
"id": "1",
"dateOfBirth": "1982-01-16",
"name": {
"firstName": "JORGE",
"lastName": "GONZALES"
},
"gender": "MALE",
"contact": {
"emailAddress": "jorge.gonzales833#telefonica.es",
"phones": [ {
"deviceType": "MOBILE",
"countryCallingCode": "34",
"number": "480080076"
} ]
},
"documents": [ {
"documentType": "PASSPORT",
"birthPlace": "Madrid",
"issuanceLocation": "Madrid",
"issuanceDate": "2015-04-14",
"number": "00000000",
"expiryDate": "2025-04-14",
"issuanceCountry": "ES",
"validityCountry": "ES",
"nationality": "ES",
"holder": true
} ]
} ]
}
MY Request using the NodeSDK
const {data:{flightOffers}} = req.body;
const {result} = await Amadeus.booking.flightOrders.post(
JSON.stringify({
'data': {
'type': 'flight-order',
'flightOffers': [ flightOffers[ 0 ] ],
'travelers': travelers
}
})
);
This is quite lengthy, but I did this so it is easy to just re-create the exact Scenario in case the issue is somewhere in the payload I am sending.
When you request Flight Create Order API, you have only put 1 traveler's information at the end that's why the error comes. you are requesting for flight order for 2 persons (1 adult and 1 child) so both information should be attached at the end.
below is a node example for the entire flow from Flight offer search, pricing, and create order. you may get a different error if some segments are not available, but the issue that you faced regarding travelers is resolved.
amadeus.shopping.flightOffersSearch.get({
originLocationCode: 'SYD',
destinationLocationCode: 'BKK',
departureDate: '2022-08-01',
adults: '1',
children: '1'
}).then(function (flightOffersResponse) {
return amadeus.shopping.flightOffers.pricing.post(
JSON.stringify({
'data': {
'type': 'flight-offers-pricing',
'flightOffers': [flightOffersResponse.data[0]]
}
})
)
}).then(function (pricingResponse) {
return amadeus.booking.flightOrders.post(
JSON.stringify({
'data': {
'type': 'flight-order',
'flightOffers': [pricingResponse.data.flightOffers[0]],
'travelers': [{
"id": "1",
"dateOfBirth": "1982-01-16",
"name": {
"firstName": "JORGE",
"lastName": "GONZALES"
},
"gender": "MALE",
"contact": {
"emailAddress": "jorge.gonzales833#telefonica.es",
"phones": [{
"deviceType": "MOBILE",
"countryCallingCode": "34",
"number": "480080076"
}]
},
"documents": [{
"documentType": "PASSPORT",
"birthPlace": "Madrid",
"issuanceLocation": "Madrid",
"issuanceDate": "2015-04-14",
"number": "00000000",
"expiryDate": "2025-04-14",
"issuanceCountry": "ES",
"validityCountry": "ES",
"nationality": "ES",
"holder": true
}]
},
{
"id": "2",
"dateOfBirth": "2012-10-11",
"gender": "FEMALE",
"contact": {
"emailAddress": "jorge.gonzales833#telefonica.es",
"phones": [
{
"deviceType": "MOBILE",
"countryCallingCode": "34",
"number": "480080076"
}
]
},
"name": {
"firstName": "ADRIANA",
"lastName": "GONZALES"
}
}]
}
})
);
}).then(function (response) {
console.log(response);
}).catch(function (response) {
console.error(response);
});

aggregate in mongodb left join with $lookup

I have three collections
posts=[
{
"id": "p1",
"title": "title 1"
},
{
"id": "p2",
"title": "title 2"
}]
users = [
{
"id": "u1",
"name": "name1"
},
{
"id": "u2",
"name": "name2"
}]
comments = [
{
"userId": "u1",
"postId": "p1",
"comment": "comment 1"
}]
I want to get all collection posts and comments in each post by userId(u1) as:
posts=[
{
"id": "p1",
"title": "title 1",
"comments":[
"userId": "u1",
"comment": "comment 1"
]
},
{
"id": "p2",
"title": "title 2",
"comments":[]
}]
I used aggregate function and $lookup operator but I don't know using the $match operator to filter userId. I used aggregate bellow:
self.db.posts.aggregate([
{
"$lookup":{
"from": "comments",
"localField": "id",
"foreignField": "postId",
"as": "comments",
}
},
{
"$match":{
"comments.userId": {"$eq": param.objectUserId}
},
},
{"$skip": (param.page - 1) * param.pageSize},
{"$limit": param.pageSize},
{"$sort": {"unixDate": pymongo.DESCENDING}}
])
It only return one post in array corresponding with userId="u1"
Please help me!
Thank all!
You have to make use of the pipeline option of $lookup stage and pass the additional conditions that you want to apply.
db.posts.aggregate([
{
"$lookup": {
"from": "comments",
"let": {
"pId": "$id"
},
"pipeline": [
{
"$match": {
"$expr": {
"$eq": [
"$postId",
"$$pId"
],
},
"userId": "u1",
},
},
{
"$project": {
"_id": 0,
"userId": 1,
"comment": 1,
},
},
],
"as": "comments"
}
}
])
Mongo Playground Sample Execution
self.db.posts.aggregate([
{
"$lookup": {
"from": "comments",
"let": {
"pId": "$id"
},
"pipeline": [
{
"$match": {
"$expr": {
"$eq": [
"$postId",
"$$pId"
],
},
"userId": param.objectUserId,
},
},
{
"$project": {
"_id": 0,
"userId": 1,
"comment": 1,
},
},
],
"as": "comments"
}
},
{"$skip": (param.page - 1) * param.pageSize},
{"$limit": param.pageSize},
{"$sort": {"unixDate": pymongo.DESCENDING}}
])

extra bag information is missing in the flight offer price response

I'm testing self-service APIs. I wonder if this is a bug:
I make a search request, and the response contains the extra bag information in the flight-offer/price/additionalServices
Then I make the offer price request by adding include=bags parameter in the path of Flight Offers Price API.
However there is no any bags information in the response, neither in the offer/price/additionalServices, nor in the included/.
I still try to create order by adding the extra bag. So I use the extra bag information that I got at step 1 (search response). And the order is created successfully.
It seems that the extra bag information is missing in step 2 (response of flight offer price), is it a bug?
Here is an example of my test to reproduce the issue:
search request
{
"currencyCode": "EUR",
"originDestinations": [
{
"id": "1",
"originLocationCode": "PAR",
"destinationLocationCode": "NYC",
"departureDateTimeRange": {
"date": "2020-08-20",
"time": "10:00:00"
}
}
],
"travelers": [
{
"id": "1",
"travelerType": "ADULT"
}
],
"sources": [
"GDS"
],
"searchCriteria": {
"maxFlightOffers": 3
}
}
Then I select the second offer in the response to make a offer price request using include=bags parameter
{
"type": "flight-offer",
"id": "2",
"source": "GDS",
"instantTicketingRequired": false,
"nonHomogeneous": false,
"oneWay": false,
"lastTicketingDate": "2020-08-13",
"numberOfBookableSeats": 8,
"itineraries": [
{
"duration": "PT8H15M",
"segments": [
{
"departure": {
"iataCode": "ORY",
"terminal": "4",
"at": "2020-08-20T19:45:00"
},
"arrival": {
"iataCode": "EWR",
"terminal": "B",
"at": "2020-08-20T22:00:00"
},
"carrierCode": "TX",
"number": "6720",
"aircraft": {
"code": "359"
},
"operating": {
"carrierCode": "BF"
},
"duration": "PT8H15M",
"id": "3",
"numberOfStops": 0,
"blacklistedInEU": false
}
]
}
],
"price": {
"currency": "EUR",
"total": "149.44",
"base": "41.00",
"fees": [
{
"amount": "0.00",
"type": "SUPPLIER"
},
{
"amount": "0.00",
"type": "TICKETING"
}
],
"grandTotal": "149.44",
"additionalServices": [
{
"amount": "70.00",
"type": "CHECKED_BAGS"
}
]
},
"pricingOptions": {
"fareType": [
"PUBLISHED"
],
"includedCheckedBagsOnly": false
},
"validatingAirlineCodes": [
"TX"
],
"travelerPricings": [
{
"travelerId": "1",
"fareOption": "STANDARD",
"travelerType": "ADULT",
"price": {
"currency": "EUR",
"total": "149.44",
"base": "41.00"
},
"fareDetailsBySegment": [
{
"segmentId": "3",
"cabin": "ECONOMY",
"fareBasis": "ULBCOWFR",
"brandedFare": "EBASIC",
"class": "U",
"includedCheckedBags": {
"quantity": 0
}
}
]
}
]
}
There is no extra bag in the response.
Thanks

How to aggregate in MongoDB using value inside array?

I have a list of products in my collection like this:
[
{
"name": "product1",
"categories": [
{
"category": "Food",
"subcategory": "Nuts"
},
{
"category": "Candies",
"subcategory": "Chocolate"
}
]
},
{
"name": "product2",
"categories": [
{
"category": "Food",
"subcategory": "Nuts"
},
{
"category": "Candies",
"subcategory": "Mint"
}
]
},
{
"name": "product3",
"categories": [
{
"category": "Food",
"subcategory": "Cakes"
},
{
"category": "Pastries",
"subcategory": "Chocolate"
}
]
}
]
I want to get a count of products using aggregate. If I run
db.collection.aggregate([{ $group: { _id: "$categories", count: { $sum: 1 }} }])
I get this:
[
{
"_id": [{ "category": "Food", "subcategory": "Nuts" }, { "category": "Candies", "subcategory": "Chocolate" }],
"count": 1
},
{
"_id": [{ "category": "Food", "subcategory": "Nuts" }, { "category": "Candies", "subcategory": "Mint" }],
"count": 1
},
{
"_id": [{ "category": "Food", "subcategory": "Cakes" }, { "category": "Pastries", "subcategory": "Chocolate" }],
"count": 1
}
]
But what I really need is to find count per category and subcategory, like this:
[
{ "_id": { "category": "Food", "subcategory": "Nuts" }, "count": 2 },
{ "_id": { "category": "Food", "subcategory": "Cakes" }, "count": 1 },
{ "_id": { "category": "Candies", "subcategory": "Chocolate" }, "count": 1 },
{ "_id": { "category": "Candies", "subcategory": "Mint" }, "count": 1 },
{ "_id": { "category": "Pastries", "subcategory": "Chocolate" }, "count": 1 }
]
Is there a query to obtain this?
You have to $unwind categories first
db.collection.aggregate([
{
$unwind: "$categories"
},
{
$group: { _id: "$categories", count: { $sum: 1 } }
}
])