Я хочу найти поля из вложенного массива в документе Монго - PullRequest
0 голосов
/ 17 июня 2019

Я не могу выбрать следующие поля из документа в mongodb

db.InsuranceRecords.find({$and:[{status: "BOOKED"}, {"products.status":"BOOKED"} ]})

db.InsuranceRecords.aggregate(
    {$match:{$and:[{status: "BOOKED"}, {"products.status":"BOOKED"} ]}},
    {$project:{        
        "tripId":1,
        "products": {$filter: {
            input: '$products',
            as: 'i',
            cond: {$eq: ['$$i.status', "BOOKED"]}
        }}
    }} )

Поля для выбора

    "tripId":1,
    "products[].internalName":1
    "products[].benefits[].internalName":1
    "products[].benefits[].cost[].amount":1
    "products[].benefits[].cost[].currencyCode":1

Из массива products будет только 1 элемент, имеющий products.status = booked. Однако я хочу прочитать внутреннее название каждого пособия, а также их сумму и код валюты.

1 Ответ

0 голосов
/ 18 июня 2019

На основе требуемого вывода вот как будет выглядеть проекционный запрос:

db.getCollection("InsuranceRecords").aggregate([
{ $match: { status: "BOOKED" } },
{
    $project: {
        _id: 0, tripId: 1, _products: {
            $filter: {
                input: '$products',
                as: 'product',
                cond: { $eq: ['$$product.status', "BOOKED"] }
            }
        }
    }
},
{
    $project: {
        tripId: 1,
        products: {
            $map: {
                "input": "$_products",
                "as": "prod",
                "in": {
                    "internalName": "$$prod.internalName",
                    "benefits": 
                        {
                            $map: {
                                "input": "$$prod.benefits",
                                "as": "benefit",
                                "in": {
                                    "internalName": "$$benefit.internalName",
                                    "cost":
                                        {
                                            $map:{
                                                "input":"$$benefit.cost",
                                                "as":"costs",
                                                "in":{
                                                    "amount":"$$costs.amount",
                                                    "currencyCode":"$$costs.currencyCode"
                                                }
                                            }
                                        }

                                }
                            }
                        }

                }
            }
        }
    }
},
{ $sort: { tripId: 1 } }
])

Который будет выводить как:

/* 1 */
{
"tripId" : 1,
"products" : [
    {
        "internalName" : "Product7",
        "benefits" : [
            {
                "internalName" : "BenefitName13",
                "cost" : [
                    {
                        "amount" : "100",
                        "currencyCode" : 1
                    },
                    {
                        "amount" : "200",
                        "currencyCode" : 2
                    }
                ]
            },
            {
                "internalName" : "BenefitName14",
                "cost" : [
                    {
                        "amount" : "300",
                        "currencyCode" : 1
                    },
                    {
                        "amount" : "400",
                        "currencyCode" : 2
                    }
                ]
            }
        ]
    }
]
},
/* 2 */
{
"tripId" : 3,
"products" : [
    {
        "internalName" : "Product3",
        "benefits" : [
            {
                "internalName" : "BenefitName5",
                "cost" : [
                    {
                        "amount" : "100",
                        "currencyCode" : 1
                    },
                    {
                        "amount" : "200",
                        "currencyCode" : 2
                    }
                ]
            },
            {
                "internalName" : "BenefitName6",
                "cost" : [
                    {
                        "amount" : "300",
                        "currencyCode" : 1
                    },
                    {
                        "amount" : "400",
                        "currencyCode" : 2
                    }
                ]
            }
        ]
    }
]
}

Объяснение

Приведенный выше запрос работает следующим образом:

  • Сначала возьмите все записи из коллекции InsuranceRecords, в которой заголовочный документ имеет status==" BOOKED".
  • Затем спроецируйте вывод с фильтром products, имеющим status==" BOOKED" ( причину не использовать это products.status:"BOOKED" в $match, так как это создаст условие and, где и головной документ, и все у продуктов есть status==" BOOKED", а в массиве нет ни одной сущности. Поэтому вместо фильтров используется ) в _products.
  • Снова спроецировал приведенный выше результат, чтобы отобразить необходимые поля из _products в products.
  • Затем отсортировали результат на основе tripId.

Образец JSON, использованный для получения вышеуказанного результата:

{
	"_id" : ObjectId("5d07685b964f7400e4de0382"),
	"name" : "Item1",
	"status" : "BOOKED",
	"products" : [
		{
			"status" : "Available",
			"internalName" : "Product1",
			"Name" : "ProductName1",
			"benefits" : [
				{
					"someProp" : "BenefitProp1",
					"internalName" : "BenefitName1",
					"cost" : [
						{
							"amount" : "100",
							"isUsed":0,
							"currencyCode" : 1
						},
						{
							"amount" : "200",
							"isUsed":1,
							"currencyCode" : 2
						}
					]
				},
				{
					"someProp" : "BenefitProp2",
					"internalName" : "BenefitName2",
					"cost" : [
						{
							"amount" : "300",
							"isUsed":0,
							"currencyCode" : 1
						},
						{
							"amount" : "400",
							"isUsed":1,
							"currencyCode" : 2
						}
					]
				}
			]
		},
		{
			"status" : "Available",
			"internalName" : "Product2",
			"Name" : "ProductName2",
			"benefits" : [
				{
					"someProp" : "BenefitProp3",
					"internalName" : "BenefitName3",
					"cost" : [
						{
							"amount" : "100",
							"isUsed":0,
							"currencyCode" : 1
						},
						{
							"amount" : "200",
							"isUsed":1,
							"currencyCode" : 2
						}
					]
				},
				{
					"someProp" : "BenefitProp4",
					"internalName" : "BenefitName4",
					"cost" : [
						{
							"amount" : "300",
							"isUsed":0,
							"currencyCode" : 1
						},
						{
							"amount" : "400",
							"isUsed":1,
							"currencyCode" : 2
						}
					]
				}
			]
		},
		{
			"status" : "BOOKED",
			"internalName" : "Product3",
			"Name" : "ProductName3",
			"benefits" : [
				{
					"someProp" : "BenefitProp5",
					"internalName" : "BenefitName5",
					"cost" : [
						{
							"amount" : "100",
							"isUsed":0,
							"currencyCode" : 1
						},
						{
							"amount" : "200",
							"isUsed":1,
							"currencyCode" : 2
						}
					]
				},
				{
					"someProp" : "BenefitProp6",
					"internalName" : "BenefitName6",
					"cost" : [
						{
							"amount" : "300",
							"isUsed":0,
							"currencyCode" : 1
						},
						{
							"amount" : "400",
							"isUsed":1,
							"currencyCode" : 2
						}
					]
				}
			]
		}
	],
	"tripId" : 3
},
{
	"_id" : ObjectId("5d07682c964f7400e4de0381"),
	"name" : "Item2",
	"status" : "Available",
	"products" : [
		{
			"status" : "BOOKED",
			"internalName" : "Product4",
			"Name" : "ProdcutName4",
			"benefits" : [
				{
					"someProp" : "BenefitProp7",
					"internalName" : "BenefitName7",
					"cost" : [
						{
							"amount" : "100",
							"isUsed":0,
							"currencyCode" : 1
						},
						{
							"amount" : "200",
							"isUsed":1,
							"currencyCode" : 2
						}
					]
				},
				{
					"someProp" : "BenefitProp8",
					"internalName" : "BenefitName8",
					"cost" : [
						{
							"amount" : "300",
							"isUsed":0,
							"currencyCode" : 1
						},
						{
							"amount" : "400",
							"isUsed":1,
							"currencyCode" : 2
						}
					]
				}
			]
		},
		{
			"status" : "BOOKED",
			"internalName" : "Product5",
			"Name" : "ProductName5",
			"benefits" : [
				{
					"someProp" : "BenefitProp9",
					"internalName" : "BenefitName9",
					"cost" : [
						{
							"amount" : "100",
							"isUsed":0,
							"currencyCode" : 1
						},
						{
							"amount" : "200",
							"isUsed":1,
							"currencyCode" : 2
						}
					]
				},
				{
					"someProp" : "BenefitProp10",
					"internalName" : "BenefitName10",
					"cost" : [
						{
							"amount" : "300",
							"isUsed":0,
							"currencyCode" : 1
						},
						{
							"amount" : "400",
							"isUsed":1,
							"currencyCode" : 2
						}
					]
				}
			]
		},
		{
			"status" : "Available",
			"internalName" : "Product6",
			"Name" : "ProductName6",
			"benefits" : [
				{
					"someProp" : "BenefitProp11",
					"internalName" : "BenefitName11",
					"cost" : [
						{
							"amount" : "100",
							"isUsed":0,
							"currencyCode" : 1
						},
						{
							"amount" : "200",
							"isUsed":1,
							"currencyCode" : 2
						}
					]
				},
				{
					"someProp" : "BenefitProp12",
					"internalName" : "BenefitName12",
					"cost" : [
						{
							"amount" : "300",
							"isUsed":0,
							"currencyCode" : 1
						},
						{
							"amount" : "400",
							"isUsed":1,
							"currencyCode" : 2
						}
					]
				}
			]
		}
	],
	"tripId" : 2
},

{
	"_id" : ObjectId("5d0767d6964f7400e4de0380"),
	"name" : "Item3",
	"status" : "BOOKED",
	"products" : [
		{
			"status" : "BOOKED",
			"internalName" : "Product7",
			"Name" : "ProductName7",
			"benefits" : [
				{
					"someProp" : "BenefitProp13",
					"internalName" : "BenefitName13",
					"cost" : [
						{
							"amount" : "100",
							"isUsed":0,
							"currencyCode" : 1
						},
						{
							"amount" : "200",
							"isUsed":1,
							"currencyCode" : 2
						}
					]
				},
				{
					"someProp" : "BenefitProp14",
					"internalName" : "BenefitName14",
					"cost" : [
						{
							"amount" : "300",
							"isUsed":0,
							"currencyCode" : 1
						},
						{
							"amount" : "400",
							"isUsed":1,
							"currencyCode" : 2
						}
					]
				}
			]
		},
		{
			"status" : "Available",
			"internalName" : "Product8",
			"Name" : "ProductName8",
			"benefits" : [
				{
					"someProp" : "BenefitProp15",
					"internalName" : "BenefitName15",
					"cost" : [
						{
							"amount" : "100",
							"isUsed":0,
							"currencyCode" : 1
						},
						{
							"amount" : "200",
							"isUsed":1,
							"currencyCode" : 2
						}
					]
				},
				{
					"someProp" : "BenefitProp16",
					"internalName" : "BenefitName16",
					"cost" : [
						{
							"amount" : "300",
							"isUsed":0,
							"currencyCode" : 1
						},
						{
							"amount" : "400",
							"isUsed":1,
							"currencyCode" : 2
						}
					]
				}
			]
		},
		{
			"status" : "Available",
			"internalName" : "Product9",
			"Name" : "ProductName9",
			"benefits" : [
				{
					"someProp" : "BenefitProp17",
					"internalName" : "BenefitName17",
					"cost" : [
						{
							"amount" : "100",
							"isUsed":0,
							"currencyCode" : 1
						},
						{
							"amount" : "200",
							"isUsed":1,
							"currencyCode" : 2
						}
					]
				},
				{
					"someProp" : "BenefitProp18",
					"internalName" : "BenefitProp18",
					"cost" : [
						{
							"amount" : "300",
							"isUsed":0,
							"currencyCode" : 1
						},
						{
							"amount" : "400",
							"isUsed":1,
							"currencyCode" : 2
						}
					]
				}
			]
		}
	],
	"tripId" : 1
}

Примечание:

  • Могут быть и другие подходы (, даже лучше ) для фильтрации вывода ( ex: курсоры ).
  • Поскольку данные выборки не были предоставлены с вопросом, я заполнил свой собственный для воспроизведения данных и требуемого вывода.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...