MongoDB-$ setIntersection与$ facet

Rah*_*Raj 1 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"]}}}]

 }}


])
Run Code Online (Sandbox Code Playgroud)

我的样本数据集是:

{
"_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")
    }
]
}
Run Code Online (Sandbox Code Playgroud)

我试图找到这在电影中两个:列表1)前10名的电影按照IMDB评分列表每Metacritic的2)前10名电影,

如果在两个列表中都看过一部或多部电影,则应过滤并显示这些电影。

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

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

我看到数组(ratingcriticcommon)是分别计算的,但是为什么我不能将它们$作为变量访问呢?有人可以告诉我怎么去的路口ratingcritic

dni*_*ess 6

您的方法还可以,我认为通过重新定位括号即可获得所需的内容。将$project阶段分为另一个阶段,而不是$ facet中的另一个阶段:

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"]}
    }
}])
Run Code Online (Sandbox Code Playgroud)

需要这样做的原因可以在文档中找到:

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