Mongodb聚合查找仅返回一个数组字段

时间:2018-01-28 20:20:23

标签: mongodb join aggregation-framework lookup

我的项目有一些收藏。

  • 投射合集包含电影广告
  • 内容集合包含电影内容

我想运行聚合查找以获取有关位置类型的电影广播的信息。

我删除了不必要字段的集合详细信息。

投射详情:

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

内容详情:

{
    "_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)
}

当我使用bellow查询运行聚合查找时,在新生成的查找数组中只有一个转换内容如果按照上面的转换数组值聚合查找应返回两个类型的转换内容。在强制转换数组值中存在两种类型的强制转换,1)作者和导演。但是返回的导演投下了内容。 _cast应该包含两个对象而不是一个对象!

聚合查询查询:

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

结果:

{
        "_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)
    }

修改-1 最后我的问题解决了。我对此查询只有一个问题,此查询不显示根文档字段。终于解决了这个问题。最终查询存在于EDIT-2中。

查询:

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"}}},
])

修改-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()

3 个答案:

答案 0 :(得分:2)

这是预期的行为。

来自docs

  

如果您的localField是一个数组,您可能想要添加$ unwind阶段   到您的管道。否则,之间的平等条件   localField和foreignField是foreignField:{$ in:[   localField.elem1,localField.elem2,...]}。

因此要使用外部字段元素连接每个本地字段数组元素,您必须$unwind本地数组。

db.content.aggregate([
  {"$unwind":"$casts"},
  {"$lookup":{"from":"casts","localField":"casts._id","foreignField":"_id","as":"_casts"}}
])

答案 1 :(得分:0)

您的Casts集合仅显示1个文档。同样,您的内容集合仅显示1个文档。

这是1比1 - 而不是1比2.聚合按设计工作。

内容文件有2"演员。"这两个演员阵营是子文件。将这些作为子文档使用,或重新设计您的集合。我不喜欢使用子文档,除非我知道我不需要将它们用作查找或加入它们。

我建议你重新设计你的收藏品。

你的内容集(它让我想起"电影")看起来像这样:

_id
title
releaseDate
genre
etc.

您可以像这样创建一个MovieCasts集合:

_id
movieId (this is _id from Contents collection, above)
castId (this is _id from Casts collection, below)

管型

_id
name
age
etc.

答案 2 :(得分:0)

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