将查找对象 id 连接到数组中

Gow*_*wri 4 mongodb mongodb-query aggregation-framework

我有业务集合,其中包含名称和类别对象 ID 数组以及品牌对象 ID 数组。

  • 业务和类别是 oneToMany
  • 业务和品牌是 oneToMany

集合结构示例

类别

{
"_id":ObjectId("595f2311f43c42124360a71f"),
"name":"Women",
}
{
"_id":ObjectId("595f2311f43c42124360a71e"),
"name":"MEN",
}
Run Code Online (Sandbox Code Playgroud)

品牌

{
"_id":ObjectId("695f2311f43c42124360a71f"),
"name":"Brand A",
}
{
"_id":ObjectId("695f2311f43c42124360a71e"),
"name":"Brand B",
}
Run Code Online (Sandbox Code Playgroud)

商业

{
 "_id":ObjectId("59a7d9e2d290a654c53bb1b6"),
 "name":"My Store",
"brands":[
 ObjectId("596e56489658851024160544"),
 ObjectId("597831971cc07f51bdaabfe6")
],
"categories":[
 ObjectId("595f2311f43c42124360a720"),
 ObjectId("59780cf7bb23af4eced57dba"),
 ObjectId("597f63f642c77654e1c8c574")
]

}
Run Code Online (Sandbox Code Playgroud)

从上面的结构尝试使用db.createView以以下格式公开数据。所以我试图查找类别集合和品牌集合以显示数组中的名称而不是对象 ID。

预期产出

{
 "_id":ObjectId("59a7d9e2d290a654c53bb1b6"),
 "j_name":"My Store",
"brands":[
 "Brand A",
 "Brand B",

],
"categories":[
 "MEN",
 "WOMEN"
]    
}
Run Code Online (Sandbox Code Playgroud)

尝试过的东西在这里,但它没有按预期工作

db.businesses.aggregate([

       { $unwind: {path:"$categories",preserveNullAndEmptyArrays: true}},
       { $lookup: {
           "from": "categories",
           "localField": "categories",
           "foreignField": "_id",
           "as": "categoryObjects"

            }
        },  
        { $unwind: {path:"$categoryObjects",preserveNullAndEmptyArrays: true}},
        // Group back to arrays
        { "$group": {
            "_id": "$_id",          
            "categoryObjects": { "$push": "$categoryObjects.name" }
        }},     

        { $project : { 
            "_id" : "$_id","j_name" :"$name","j_keywords" : "$keywords","rating":"$rating.overAll","logo":"$logo",
            "j_l_city" : "$address.city","j_l_area" : "$address.area","location":{$concat : ["$address.lat", ",", "$address.lng"]},
            "attr_payments":"$attributes.payments","attr_delivery":"$attributes.delivery","attr_parking":"$attributes.parking",         "attr_locatedAt":"$attributes.locatedAt","attr_tailoring":"$attributes.tailoring","attr_wifi":"$attributes.wifi","attr_kidspark":"$attributes.kidspark",
            "j_categories":"$categoryObjects",
             }}
         ])
Run Code Online (Sandbox Code Playgroud)

chr*_*dam 5

更好的管道是:

db.business.aggregate([
    { "$lookup": {
        "from": "categories",
        "localField": "categories",
        "foreignField": "_id",
        "as": "categories"
    } },
    { "$lookup": {
        "from": "brands",
        "localField": "brands",
        "foreignField": "_id",
        "as": "brands"
    } },
    { "$addFields": {
        "brands": "$brands.name",
        "categories": "$categories.name"
    } }
]);
Run Code Online (Sandbox Code Playgroud)

这也与

db.business.aggregate([
    { "$lookup": {
        "from": "categories",
        "localField": "categories",
        "foreignField": "_id",
        "as": "categories"
    } },
    { "$lookup": {
        "from": "brands",
        "localField": "brands",
        "foreignField": "_id",
        "as": "brands"
    } },
    { "$addFields": {
        "brands": {
            "$map": {
                "input": "$brands",
                "as": "brand",
                "in": "$$brand.name"
            } 
        },
        "categories": {
            "$map": {
                "input": "$categories",
                "as": "cat",
                "in": "$$cat.name"
            } 
        }  
    } }
]);
Run Code Online (Sandbox Code Playgroud)