我想从mongo文档中的嵌套数组中查找字段

时间:2019-06-17 07:28:25

标签: mongodb aggregation-framework

我无法从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。但是,我想读取每种福利的内部名称及其金额和currencyCode。

1 个答案:

答案 0 :(得分:0)

根据此处要求的输出,投影查询将如下所示:

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的原因,因为它将创建一个{{1} },其中主文档和所有产品都具有and而不是数组中的单个实体。因此,请使用过滤器将产品获取。)放入status==" BOOKED"
  • 再次将以上结果投影为将_products中的必填字段映射到_products中。
  • 然后根据products对结果进行排序。

用于产生上述结果的示例json:

tripId

注意:

  • 还有其他方法(更好)来过滤输出( ex:cursors )。
  • 由于示例数据没有提供问题,因此我自己填写了数据以再现数据和所需的输出。