Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mongodb aggregate lookup return only one field of array

i have some collections for our project.

  • Casts collection contains movie casts
  • Contents collection contains movie contents

i want to run aggregate lookup for get information about movie casts with position type.

i removed collections details unnecessary fields.

Casts details:

{
    "_id" : ObjectId("5a6cf47415621604942386cd"),
    "fa_name" : "",
    "en_name" : "Ehsan",
    "fa_bio" : "",
    "en_bio" : ""
}

Contents details:

{
    "_id" : ObjectId("5a6b8b734f1408137f79e2cc"),

    "casts" : [ 
        {
            "_id" : ObjectId("5a6cf47415621604942386cd"),
            "fa_fictionName" : "",
            "en_fictionName" : "Ehsan2",
            "positionType" : {
                "id" : 3,
                "fa_name" : "",
                "en_name" : "Director"
            }
        }, 
        {
            "_id" : ObjectId("5a6cf47415621604942386cd"),
            "fa_fictionName" : "",
            "en_fictionName" : "Ehsan1",
            "positionType" : {
                "id" : 3,
                "fa_name" : "",
                "en_name" : "Writers"
            }
        }
    ],
    "status" : 0,
    "created" : Timestamp(1516997542, 4),
    "updated" : Timestamp(1516997542, 5)
}

when i run aggregate lookup with bellow query, in new generated lookup array only one casts contents If in accordance with above casts array value aggregate lookup should return two casts content with two type. in casts array value exists two type of casts, 1) writers and directors. but returned director casts content. _casts should contains two object not one object!

aggregate lookup query:

{$lookup:{from:"casts",localField:"casts._id",foreignField:"_id",as:"_casts"}}

result:

{
        "_id" : ObjectId("5a6b8b734f1408137f79e2cc"),

        "casts" : [ 
            {
                "_id" : ObjectId("5a6cf47415621604942386cd"),
                "fa_fictionName" : "",
                "en_fictionName" : "Ehsan2",
                "positionType" : {
                    "id" : 3,
                    "fa_name" : "",
                    "en_name" : "Director"
                }
            }, 
            {
                "_id" : ObjectId("5a6cf47415621604942386cd"),
                "fa_fictionName" : "",
                "en_fictionName" : "Ehsan1",
                "positionType" : {
                    "id" : 3,
                    "fa_name" : "",
                    "en_name" : "Writers"
                }
            }
        ],
    "_casts" : [ 
           {
            "_id" : ObjectId("5a6cf47415621604942386cd"),
            "fa_name" : "",
            "en_name" : "Ehsan",
            "fa_bio" : "",
            "en_bio" : ""
           }
        ],
        "status" : 0,
        "created" : Timestamp(1516997542, 4),
        "updated" : Timestamp(1516997542, 5)
    }

EDIT-1 finally my problem is solved. i have only one problem with this query, this query doesn't show root document fields. finally solve this problem. finally query exists in EDIT-2.

query:

db.contents.aggregate([ 
{"$unwind":"$casts"},
{"$lookup":{"from":"casts","localField":"casts._id","foreignField":"_id","as":"casts.info"}},
{"$unwind":"$casts.info"},
{"$group":{"_id":"$_id", "casts":{"$push":"$casts"}}},
])

EDIT-2

db.contents.aggregate([ 
{"$unwind":"$casts"},
{"$lookup":{"from":"casts","localField":"casts._id","foreignField":"_id","as":"casts.info"}},
{"$unwind":"$casts.info"},
{$group:{"_id":"$_id", "data":{"$first":"$$ROOT"}, "casts":{"$push":"$casts"}}},
{$replaceRoot:{"newRoot":{"$mergeObjects":["$data",{"casts‌​":"$casts"}]}}},
{$project:{"casts":0}}
]).pretty()
like image 687
Ehsan Farahani Asil Avatar asked Oct 26 '25 04:10

Ehsan Farahani Asil


2 Answers

This is expected behavior.

From the docs,

If your localField is an array, you may want to add an $unwind stage to your pipeline. Otherwise, the equality condition between the localField and foreignField is foreignField: { $in: [ localField.elem1, localField.elem2, ... ] }.

So to join each local field array element with foreign field element you have to $unwind the local array.

db.content.aggregate([
  {"$unwind":"$casts"},
  {"$lookup":{"from":"casts","localField":"casts._id","foreignField":"_id","as":"_casts"}}
])
like image 185
s7vr Avatar answered Oct 28 '25 04:10

s7vr


Vendor Collection

Items Collection

db.items.aggregate([
                      { $match:
                              {"item_id":{$eq:"I001"}}
                      },
                      { 
                        $lookup:{  
                                    from:"vendor",
                                    localField:"vendor_id",
                                    foreignField:"vendor_id",
                                    as:"vendor_details"
                                 }
                      },
                      {
                       $unwind:"$vendor_details"
                      },
                      {
                        $project:{ 
                                  "_id":0,
                                  "vendor_id":0,
                                  "vendor_details.vendor_company_description":0,
                                  "vendor_details._id":0,
                                  "vendor_details.country":0,
                                  "vendor_details.city":0,
                                  "vendor_details.website":0
                                  }
                        }
                     ]);

Output

like image 43
Aravind KR Avatar answered Oct 28 '25 02:10

Aravind KR



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!