node.js - Mongoose 聚合并获得点赞数
问题描述
我有一个关于 Mongoose 聚合的查询。我一直在尝试分别获取用户详细信息以及喜欢和爱计数及其关系,但我无法成功。
这是我的场景,我有一个用户表和反应表。用户表包含用户详细信息,反应表包含用户详细信息以及喜欢用户的其他信息。在我的模式中,它是类型,例如:type='like' 或 love,所以我需要获取用户详细信息以及喜欢的数量。我是 MongoDB 的新手。
这是我的代码:
用户模式
// Importing Node packages required for schema
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const validateEmail = function(email) {
const re = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/;
return re.test(email)
};
//= ===============================
// User Schema
//= ===============================
const UserSchema = new Schema({
email: {
type: String,
trim: true,
lowercase: true,
},
reactions : [
{ type: Schema.Types.ObjectId, ref: 'ProfileReaction' }
],
},
{
timestamps: true
}
);
module.exports = mongoose.model('User', UserSchema);
反应图式
const mongoose = require('mongoose'),
Schema = mongoose.Schema;
const ProfileReactionSchema = new Schema({
likedBy: {
type: Schema.Types.ObjectId,
ref: 'User',
required: true,
index: true
},
user: {
type: Schema.Types.ObjectId,
ref: 'User',
required: true,
index: true
},
type: {
type: String,
required: true,
},
},
{
timestamps: true // Saves createdAt and updatedAt as dates. createdAt will be our timestamp.
}
);
module.exports = mongoose.model('ProfileReaction', ProfileReactionSchema);
我真正想要的是下面的东西
{
_id: '1234',
email: 'xyz@gmail.com',
reactions: [
{
_id: '1235',
likedBy: {...},
user: {...},
type: 'like'
},
{
_id: '1236',
likedBy: {...},
user: {...},
type: 'love'
}
],
noOfLikes: 1,
noOfLoves: 1
}
到目前为止我所尝试的是,但这只是给了我关系,但我没有得到喜欢和爱的数量。但我需要他们都喜欢计数,喜欢计数和关系
const user = await User.findOne({$or: [
req.params.id.match(/^[0-9a-fA-F]{24}$/) ? {_id: mongoose.Types.ObjectId(req.params.id)}
: {uid: req.params.id}
]}).populate([
{
path: 'reactions',
model: 'ProfileReaction',
populate: [
{
path: 'likedBy',
model: 'User'
}
]
}
]);
我正在使用版本mongoose v5.6.10
。
解决方案
您可以使用以下$lookup
聚合
User.aggregate([
{ "$match": {
"$or": [
req.params.id.match(/^[0-9a-fA-F]{24}$/)
? { "_id": mongoose.Types.ObjectId(req.params.id) }
: { "uid": req.params.id }
]
}},
{ "$lookup": {
"from": ProfileReaction.collection.name,
"let": { "reactions": "$reactions" },
"pipeline": [
{ "$match": {
"$expr": { "$in": ["$_id", "$$reactions"] },
"type": "like"
}}
],
"as": "likeReactions"
}},
{ "$lookup": {
"from": ProfileReaction.collection.name,
"let": { "reactions": "$reactions" },
"pipeline": [
{ "$match": {
"$expr": { "$in": ["$_id", "$$reactions"] },
"type": "love"
}}
],
"as": "loveReactions"
}},
{ "$addFields": {
"noOfLikes": { "$size": "$likeReactions" },
"noOfLoves": { "$size": "$loveReactions" }
}}
])
推荐阅读
- excel - 如何通过颜色编码表示不同的状态?
- selenium - Selenium 单击具有更高 z-index 的 div 后面的按钮
- javascript - for 循环在 div 中错误地打印 i
- ruby-on-rails - 同一对象上的多个多态关联
- oracle - Oracle CLOB 列和 LAG
- javascript - 存储按钮点击
- c# - 带有 SteamVR 的 RenderTexture 与标准 Unity 相机不同
- python - 在组内使用 pandas.shift()
- cloud-foundry - CloudFouncdy CLI 和多租户,许多环境/部署
- android - 为什么 BLE 设备在 API 级别 26+ 一天后断开连接?