MongoDB - 带$ facet的$ setIntersection

时间:2018-03-26 18:32:04

标签: mongodb mongodb-query aggregation-framework

这是我的疑问:

db.movies.aggregate([
   {$facet:{
        rating:[{$match: {"imdb.rating":{$gte: 0},"metacritic":{$gte: 0}}}, 
   {$sort: {"imdb.rating":-1}},{$project: 
   {"title":1,"imdb.rating":1,"metacritic":1}},{$limit: 10}],

     critic:[{$match: {"metacritic":{$gte: 0},"imdb.rating":{$gte: 0}}}, 
   {$sort: {"metacritic": -1}},{$project: 
   {"title":1,"imdb.rating":1,"metacritic":1}},{$limit: 10}],

     intersection:[{$project: {common: {$setIntersection: 
   ["$rating","$critic"]}}}]

 }}


])

我的样本数据集是:

{
"_id" : ObjectId("573a13cef29313caabd8709c"),
"title" : "Justin Bieber: Never Say Never",
"year" : 2011,
"runtime" : 105,
"released" : ISODate("2011-02-11T00:00:00.000Z"),
"cast" : [ 
    "Justin Bieber", 
    "Boys II Men", 
    "Miley Cyrus", 
    "Sean Kingston"
],
"metacritic" : 52,
"poster" : "http://ia.media-imdb.com/images/M/MV5BMTY0NDQzMjIzOF5BMl5BanBnXkFtZTcwNDk2NzczNA@@._V1_SX300.jpg",
"plot" : "Follows Justin Bieber with some footage of performances from his 2010 concert tour.",
"fullplot" : "The camera follows Justin Bieber (1994- ) during the ten days leading up to his August, 2010, sold-out show at Madison Square Garden. Footage of these ten days of concerts, rehearsals, and down time with boyhood friends, his mom, and his entourage is inter-cut with home movies, old photos, and interviews showing a musical prodigy who loves to perform, comes to the attention of an Atlanta agent via YouTube, impresses Usher, and rockets to international stardom soon after his 15th birthday. His manager emphasizes the importance of social media and of Justin's work ethic and personality in making him a star; the camera emphasizes Bieber's look. His mom and grandparents shine.",
"awards" : "2 wins & 6 nominations.",
"lastupdated" : "2015-08-23 00:33:04.327000000",
"type" : "movie",
"languages" : [ 
    "English"
],
"directors" : [ 
    "Jon M. Chu"
],
"imdb" : {
    "rating" : 1.6,
    "votes" : 73548,
    "id" : 1702443
},
"countries" : [ 
    "USA"
],
"rated" : "G",
"genres" : [ 
    "Documentary", 
    "Music"
],
"tomatoes" : {
    "website" : "http://www.JustinBieberNeverSayNever.com",
    "viewer" : {
        "rating" : 3.5,
        "numReviews" : 61961,
        "meter" : 65
    },
    "dvd" : ISODate("2011-05-13T00:00:00.000Z"),
    "rotten" : 37,
    "boxOffice" : "$73.0M",
    "consensus" : "As a tour documentary, it's rather uninspired -- but as a 3D glimpse of a building pop culture phenomenon, Never Say Never is undeniably entertaining.",
    "critic" : {
        "rating" : 5.8,
        "numReviews" : 102,
        "meter" : 64
    },
    "production" : "Paramount Pictures",
    "lastUpdated" : ISODate("2015-08-18T19:05:06.000Z"),
    "fresh" : 65
},
"num_mflix_comments" : 2,
"comments" : [ 
    {
        "name" : "Petyr Baelish",
        "email" : "aidan_gillen@gameofthron.es",
        "movie_id" : ObjectId("573a13cef29313caabd8709c"),
        "text" : "A earum quae quos perspiciatis tempora natus. Voluptatem quod cum illum magni reiciendis. Labore exercitationem velit suscipit dicta.",
        "date" : ISODate("2009-05-10T13:15:19.000Z")
    }, 
    {
        "name" : "Daario Naharis",
        "email" : "michiel_huisman@gameofthron.es",
        "movie_id" : ObjectId("573a13cef29313caabd8709c"),
        "text" : "Ut quod rem rem dolor voluptatum necessitatibus sapiente. Ea nulla dignissimos iste porro natus eveniet eum. Quidem sit totam libero iusto repudiandae ab ducimus. Facere nesciunt assumenda ab.",
        "date" : ISODate("1992-02-17T22:39:11.000Z")
    }
]
}

我正在尝试找到两者中的电影: 列表1)根据imdb评级排名前10的电影 清单2)按照元杂技的前10部电影

如果在两个列表中都看到一部或多部电影,则应对其进行过滤和显示。

intersection:[{$project: {common: {$setIntersection:["$rating","$critic"]}}}]

此部分无效,我甚至尝试匹配标题$setIntersection:["$rating.title","$critic.title"]

我看到阵列(ratingcritic& common)是单独计算的,但为什么我不能以$作为变量访问那些数组呢?有人可以告诉我如何获得ratingcritic的交集吗?

2 个答案:

答案 0 :(得分:4)

你的方法还可以,我认为通过重新定位括号,你可以获得你想要的东西。将db.movies.aggregate([{ $facet:{ rating:[ {$match:{"imdb.rating":{$gte: 0},"metacritic":{$gte: 0}}}, {$sort:{"imdb.rating":-1}}, {$project:{"title":1,"imdb.rating":1,"metacritic":1}}, {$limit:10} ], critic:[ {$match:{"metacritic":{$gte: 0},"imdb.rating":{$gte: 0}}}, {$sort:{"metacritic": -1}}, {$project:{"title":1,"imdb.rating":1,"metacritic":1}}, {$limit:10} ] } }, { $project:{ common:{$setIntersection:["$rating","$critic"]} } }]) 阶段分成另一个阶段,而不是$ facet中的另一个阶段:

ng-init

需要这样做的原因可以在documentation

中找到
  

$ facet中的每个子管道都传递完全相同的输入集   文档。这些子管道完全独立于一个   另一个和每个输出的文档数组分开存储   输出文档中的字段。一个子管道的输出不能   用作同一个不同子管道的输入   $ facet阶段。如果需要进一步聚合,请添加其他聚合   $ facet之后的阶段并指定字段名称   期望的子管道输出。

答案 1 :(得分:-1)

db.movies.aggregate([ { $facet: {
                        'imdb_rating': [  {$match : { 'imdb.rating': { '$gte' :0},"metacritic":{$gte: 0}}},
                                          { $project: { _id : 0 , "imdb.rating" : 1, "title" : 1}},
                                          { $sort :{ 'imdb.rating' : -1, 'title' : -1}},
                                          { $limit : 10}, {$project : { 'title': 1}}
                                       ],
                        'metacritic' : [  {$match : { 'metacritic': { '$gte' :0},'imdb.rating': { '$gte' :0}}},
                                          { $project: { _id : 0 , "metacritic" : 1, "title" : 1}},
                                          { $sort :{ 'metacritic' : -1, 'title' : -1}},
                                          { $limit : 10}, {$project : { 'title': 1}}
                                       ]}},
                        {$project : {rating_title : '$imdb_rating.title',meta_title : '$metacritic.title'}},
                        {$project : {size :{ $size :{ $setIntersection : ['$rating_title', '$meta_title']}}}}
                    ]).pretty()