Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/38.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js 猫鼬:带过滤功能的无限滚动_Node.js_Mongodb_Mongoose_Nosql_Mern - Fatal编程技术网

Node.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

我有这两种型号:

User.js

Profile.js

以下是
用户
文档的示例:

{
  "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”]
通常,无限滚动很容易,因为我只需按存储顺序2×2加载文档,而无需对任何字段进行过滤。
示例:在无限滚动中两个接两个地显示跟随的用户

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
      用户
      集合中使用聚合管道进行以下操作
    • $match
      以下id条件
    • $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,
      }
    });