首页 > 解决方案 > MongoDB 聚合 - 过滤子数组并投影其部分数据

问题描述

我有看起来像这样的文件

每个文档都包含“书籍”和“电影”,但我不知道每个文档有多少。

{ 
    "_id" : 1, 
    "books" : [
        {
            "title" : "Philosopher's Stone", 
            "PopularVote" : 10, 
            "CriticsVote" : 9 
        },
        {
            "title" : "Chamber of Secrets", 
            "PopularVote" : 8, 
            "CriticsVote" : 6 
        },
        {
            "title" : "Prisoner of Azkaban", 
            "PopularVote" : 2, 
            "CriticsVote" : 10 
        }
    ],
    "movies" : [
        {
            "title" : "Goblet of Fire", 
            "PopularVote" : 5, 
            "CriticsVote" : 10 
        },
        {
            "title" : "Order of the Phoenix", 
            "PopularVote" : 8, 
            "CriticsVote" : 9 
        }
    ]       
}       

我只想选择在 PopularVote 或 CriticsVote 上获得 10 分的数组并仅投影标题。结果应该是这样的。

{ 
    "_id" : 1, 
    "books" : [
        {
            "title" : "Philosopher's Stone",  
        },
        {
            "title" : "Prisoner of Azkaban",  
        }
    ],
    "movies" : [
        {
            "title" : "Goblet of Fire", 
        }
    ]       
}    

我尝试了各种$filtercond: 的组合,但失败了。

谢谢!

ps哈利波特迷们,这只是一个数据示例,并不反映我对书籍和电影的看法(-:

标签: mongodbaggregation-framework

解决方案


使用$addFields$filter替换现有booksmovies应用过滤条件,然后您可以使用$project仅获取标题,尝试:

db.col.aggregate([
    {
        $addFields: {
            books: {
                $filter: {
                    input: "$books",
                    as: "b",
                    cond: {
                        $or: [
                            { $eq: [ "$$b.PopularVote", 10 ] },
                            { $eq: [ "$$b.CriticsVote", 10 ] }
                        ]
                    }
                }
            },
            movies: {
                $filter: {
                    input: "$movies",
                    as: "m",
                    cond: {
                        $or: [
                            { $eq: [ "$$m.PopularVote", 10 ] },
                            { $eq: [ "$$m.CriticsVote", 10 ] }
                        ]
                    }
                }
            }
        }
    },
    {
        $project: {
            "books.title": 1,
            "movies.title": 1
        }
    }
])

推荐阅读