Node.js 猫鼬:带过滤功能的无限滚动
我有这两种型号: User.js Profile.js 以下是Node.js 猫鼬:带过滤功能的无限滚动,node.js,mongodb,mongoose,nosql,mern,Node.js,Mongodb,Mongoose,Nosql,Mern,我有这两种型号: User.js Profile.js 以下是用户文档的示例: { "following": [ { "profile":{ "videoURL":"video_url_1" } }, { "profile":{ "videoURL":"video_url
用户
文档的示例:
{
"following": [
{
"profile":{
"videoURL":"video_url_1"
}
},
{
"profile":{
"videoURL":"video_url_2"
}
},
{
"profile":{}
},
{
"profile":{
"videoURL":"video_url_3"
}
},
{
"profile":{
"videoURL":"video_url_4"
}
},
{
"profile":{
"videoURL":"video_url_5"
}
},
{
"profile":{}
},
{
"profile":{
"videoURL":"video_url_6"
}
}
]
}
我正试图实现一个无限滚动的视频用户的连接后,用户
这意味着,我必须筛选user.following.profile.videoURL
存在videoURL的位置
假设我将通过两个视频加载两个视频:
- 答复1:[“视频url 1”、“视频url 2”]
- 答复2:[“视频url 3”、“视频url 4”]
- 答复3:[“视频url 5”、“视频url 6”]
示例:在无限滚动中两个接两个地显示跟随的用户
User.findById(user_id).populate({
path: "following",
options: {
skip: 2 * page,
limit: 2,
},
});
但是,现在我必须对每个后续的_user.profile.video执行过滤,然后逐个返回。我不知道如何同时执行过滤和无限滚动
注意:根据: 通常,无法根据故事作者的属性使populate()过滤故事。例如,下面的查询不会返回任何结果,即使已填充author 所以我想,我没有办法根据每个
用户.followers.profile.videoURL
使用“填充”来过滤基于的user.followers
,所以您需要的是具有无限滚动的表和:
您可以选择给定的方法来解决您的问题:
我不确定使用populate方法是否可行,但您可以尝试聚合管道
$match
条件用户id
在$lookup
集合中使用聚合管道进行以下操作用户
以下id条件$match
带有$lookup
用于配置文件
以下内容。配置文件
$match
应该存在视频URL
显示$project
字段并使用配置文件
$arrayElemAt
在$slice
后面的
中进行分页
建议: 您可以改进您的模式设计
- 删除配置文件架构并在用户集合中添加配置文件对象,这样您可以使用填充方法轻松实现您的需求
- 将匹配条件放入以下填充中,以填充
是否存在videoURL
我不明白你的意思。你能解释一下你想做什么样的过滤吗?我的错,我将不得不过滤user.following.profile.videoURL其中videoURL存在你发布的内容可以用populate实现。问题是,当我在profile.videoURL上添加过滤时,我并没有找到一种使用populate的方法。你没有在聚合解决方案中提到它。我告诉过你这是过滤条件“user.following.profile.videoURL WHERE videoURL exists”。我认为您所建议的,将从下面的数组中返回前两个用户,并且只使用筛选条件填充概要文件,然后填充后两个用户,依此类推。但是,我只想让它从following.profile.videoURL所在的以下数组返回用户。我使用populate进行了查找,但这是不可能的,我已经根据您的populate查询更新了聚合查询。这很有效。非常感谢。我已经添加了一个建议,如果您只是计划并开始开发,您可以改进这些东西,nosql规则是避免更多的收集,尝试管理更少的收集。避免加入。
{
"following": [
{
"profile":{
"videoURL":"video_url_1"
}
},
{
"profile":{
"videoURL":"video_url_2"
}
},
{
"profile":{}
},
{
"profile":{
"videoURL":"video_url_3"
}
},
{
"profile":{
"videoURL":"video_url_4"
}
},
{
"profile":{
"videoURL":"video_url_5"
}
},
{
"profile":{}
},
{
"profile":{
"videoURL":"video_url_6"
}
}
]
}
User.findById(user_id).populate({
path: "following",
options: {
skip: 2 * page,
limit: 2,
},
});
const story = await Story.
findOne({ 'author.name': 'Ian Fleming' }).
populate('author').
exec();
story; // null
let page = 0;
let limit = 2;
let skip = limit * page;
User.aggregate([
{ $match: { _id: mongoose.Types.ObjectId(user_id) } },
{
$lookup: {
from: "users",
let: { following: "$following" },
pipeline: [
{ $match: { $expr: { $in: ["$_id", "$$following"] } } },
{
$lookup: {
from: "profiles",
localField: "profile",
foreignField: "_id",
as: "profile"
}
},
{ $match: { "profile.videoURL": { $exists: true } } },
{
$project: {
profile: { $arrayElemAt: ["$profile", 0] }
}
}
],
as: "following"
}
},
{
$addFields: {
following: {
$slice: ["$following", skip, limit]
}
}
}
])
const UserSchema = new Schema({
profile: {
type: {
videoURL: {
type: String
}
}
},
following: [
{
type: Schema.Types.ObjectId,
ref: "users"
}
]
});
module.exports = User = mongoose.model("users", UserSchema);
User.findById(user_id).populate({
path: "following",
match: {
"profile.videoURL": { $ne: null }
},
options: {
skip: 2 * page,
limit: 2,
}
});