Mongodb 如何在查找聚合后按id查找
我在mongodb中有一个新闻文章集合,另一个集合将用户ID映射到文章ID,并具有“like”状态,如果用户和文章不存在条目,则状态可以是“like”或“loke”或“none” 以下是两种模式:Mongodb 如何在查找聚合后按id查找,mongodb,mongodb-query,aggregation-framework,Mongodb,Mongodb Query,Aggregation Framework,我在mongodb中有一个新闻文章集合,另一个集合将用户ID映射到文章ID,并具有“like”状态,如果用户和文章不存在条目,则状态可以是“like”或“loke”或“none” 以下是两种模式: // news collection const articleSchema = new Schema({ title: String, content: String, }) // newslikes collection const articleLikeSchema = new Sch
// 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
?您可以在mongodb3.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"] }
}}
])
或者你尝试的方式
基本上,这里您需要为字段userLikeStatus
设置,也就是说,如果数组后面的值为1,那么用户喜欢它,否则不喜欢
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": {
"$let": {
"vars": {
"array": {
"$filter": {
"input": "$likes",
"as": "like",
"cond": { "$eq": ["$$like.user", mongoose.Types.ObjectId("5ccf13adcec5e6d84f940417")] }
}
}
},
"in": {
"$ifNull": [{ "$arrayElemAt": ["$$array.state", 0] }, "none"]
}
}
}
}}
])
我不明白为什么它里面有一个
$cond
,然后是一个$gt
和一个$filter
,所以第一种方法有一个错误:$in需要一个数组作为第二个参数,发现:objectId
这不是我真正想要的。我想要一个like状态字符串,如果行不存在,它可以是“like”或“loke”或“none”。我不想要一个简单的布尔值,大多数时候我都不测试。我刚刚记住的大部分语法。我已经测试了昨天发布的代码,但是现在我很忙,无法测试它。给我最后一次机会。如果你已经发布了真实的数据和样本输出,那么直到我正确回答你为止。