我的文件如下,
{
"_id" : ObjectId("5539d45ee3cd0e48e99c3fa6"),
"userId" : 1,
"movieId" : 6,
"rating" : 2.0000000000000000,
"timestamp" : 9.80731e+008
}
然后我需要为给定的两个用户(如userId:1和userId:2)获取公共(交叉)项目
例如,
{
"_id" : ObjectId("5539d45ee3cd0e48e99c1fa7"),
"userId" : 1,
"movieId" : 22,
"rating" : 3.0000000000000000,
"timestamp" : 9.80731e+008
},
{
"_id" : ObjectId("5539d45ee3cd0e48e99c1fa8"),
"userId" : 1,
"movieId" : 32,
"rating" : 2.0000000000000000,
"timestamp" : 9.80732e+008
},
{
"_id" : ObjectId("5539d45ee3cd0e48e99c1fa9"),
"userId" : 2,
"movieId" : 32,
"rating" : 4.0000000000000000,
"timestamp" : 9.80732e+008
},
{
"_id" : ObjectId("5539d45ee3cd0e48e99c1fa3"),
"userId" : 2,
"movieId" : 6,
"rating" : 5.0000000000000000,
"timestamp" : 9.80731e+008
}
然后我需要得到结果[6,32] 我试着这样做,
aggregate([{"$match":{"$or":[{"userId":2},{"userId":1}]}},{"$group":{"_id":"$userId","movie":{"$addToSet":"$movieId"}}}])
但是没有用。
我该怎么做?
答案 0 :(得分:0)
试试这个:
db.movies.aggregate(
// Limit rating records to the relevant users
{$match:{userId:{$in:[1,2]}}},
// For each movie rated by either user, keep track of how many users rated the movie.
{$group:{_id:'$movieId',users:{$sum:1}}},
// Restrict the result to only movies rated by both users.
{$match:{users:2}}
)
答案 1 :(得分:0)
使用set operators可以获得所需的结果,过滤掉相同用户/电影对的可能重复条目:
db.collection.aggregate([
{$match: {"$or":[{"userId":2},{"userId":1}]}},
{$group: {_id: "$movieId", users: {$addToSet: "$userId"}}},
{$project: { movieId: "$_id", _id: 0, allUsersIncluded: { $setIsSubset: [ [1,2], "$users"]}}},
{$match: { allUsersIncluded: true }},
{$group: { _id: null, movies: {$addToSet: "$movieId"}}}
])
根据你的例子制作:
{ "_id" : null, "movies" : [ 32, 6 ] }
$match
阶段将只保留用户1或2的文档; $group
阶段将使用$addToSet
为每个电影构建知道该电影的用户组; users
[1]
,[2]
,[1,2]
或[2,1]
。使用$setIsSubset
我会在以下$project
/ $match
阶段过滤掉前两种情况;