我在mongodb中有一组新闻文章,另一个是将用户ID映射到文章ID并具有“喜欢”状态的集合,如果没有条目,状态可以为“喜欢”或“不喜欢”或“无”与用户和文章存在。
这是两个模式:
// news collection
const articleSchema = new Schema({
title: String,
content: String,
})
// newslikes collection
const articleLikeSchema = new Schema({
user: { type: Schema.Types.ObjectId, ref: 'Client' },
article: { type: Schema.Types.ObjectId, ref: 'News' },
state: { type: String, enum: ['like', 'dislike'] }
})
我正在尝试编写一个聚合查询,该查询使用$lookup
将这两个集合连接在一起,然后在所有文章中查找特定用户的状态。这是我到目前为止的内容:
const results = await News.aggregate([
{ $match: query },
{ $sort: { date: -1 } },
{ $skip: page * pageLength },
{ $limit: pageLength },
{ $lookup: {
from: 'newslikes',
localField: '_id',
foreignField: 'article',
as: 'likes'
} },
{ $project: {
title: 1,
likes: 1,
content: 1,
// numLikes: { $size: '$likes' }
userLikeStatus: {
$filter: {
input: '$likes',
as: 'like',
cond: {
$eq: ['$user._id', '5ccf13adcec5e6d84f940417']
}
}
}
} }
])
但是这不起作用。我在做什么甚至是正确的方法,还是有比$filter
更好的方法呢?
答案 0 :(得分:1)
您可以在mongodb 3.6 及更高版本
中使用以下聚合News.aggregate([
{ "$match": query },
{ "$sort": { "date": -1 } },
{ "$skip": page * pageLength },
{ "$limit": pageLength },
{ "$lookup": {
"from": "newslikes",
"let": { "articleId": "$_id" },
"pipeline": [
{ "$match": {
"$expr": { "$eq": [ "$article", "$$articleId" ] },
"user": mongoose.Types.ObjectId("5ccf13adcec5e6d84f940417")
}}
],
"as": "likes"
}},
{ "$addFields": {
"userLikeStatus": { "$ifNull": [{ "$arrayElemAt": ["$likes.state", 0] }, "none"] }
}}
])
或者您尝试的方式
基本上,您需要在字段{{1}中放置$cond
,即如果$size
之后的数组的$filter
为$gte
1,则用户喜欢它否则没有。
userLikeStatus