【问题标题】:MongoDB Find Next Document or Go To FirstMongoDB 查找下一个文档或转到第一个
【发布时间】:2017-01-18 03:49:35
【问题描述】:

我有一个带有 Node / MongoDB / Mongoose ODM 的 Express 应用程序。该应用程序显示有关存储在 DB 中的项目的数据,每个项目页面都应该有一个指向上一个和下一个项目的链接(该链接也存储在 DB 中)。如果应用程序位于数据库中的最后一个项目,我如何在数据库中查询第一个项目,而不是寻找(不存在的)下一个项目?

app.get('/projects/:_id', function(req, res){
var nextProject = Project.find({_id: {$gt: req.params._id}}).sort({_id: 1 }).limit(1)
var prevProject = Project.find({_id: {$lt: req.params._id}}).sort({_id: -1 }).limit(1)
Project.findById(req.params._id, function(err, foundProject){
  if(err){
    console.log('Error finding project');
    console.log(err);
  } else {
      nextProject.exec(function(err, next){
        if(err){
          console.log('err');
          console.log(err);
        } else {
          prevProject.exec(function(err, prev){
            if(err){
              console.log('err');
              console.log(err);
            } else {
              console.log(prev[0].title);
              console.log('==============================================');
              console.log(foundProject);
              console.log('==============================================');
              console.log(next[0].title);
              res.render('project', {project: foundProject, nextProject: next[0], prevProject: prev[0]});
            }
          });
        }
      });
    }
  });
});

谢谢!

EDIT(如果“下一个”返回为空,则新代码尝试检索第一个文档...

app.get('/projects/:_id', function(req, res){
Project.find({_id: {$gt: req.params._id}}).sort({_id: 1 }).limit(1), function(err, next){
  if(err){
    console.log('err getting next project');
    console.log(err);
  } else if(next){
    var nextProject = next
    console.log('this is the next project');
    console.log(nextProject);
  } else {
    var nextProject = Project.find().sort({_id: 1 }).limit(1);
    console.log('this is the first project');
    console.log(nextProject);
  }
}
Project.find({_id: {$lt: req.params._id}}).sort({_id: -1 }).limit(1), function(err, prev){
  if(err){
    console.log('error getting previous project');
    console.log(err);
  } else if(prev){
    var prevProject = prev
    console.log('this is the previous project');
    console.log('prevProject');
  } else {
    var prevProject = Project.find().sort({_id: -1}).limit(1);
    console.log('this is the last project');
    console.log(prevProject);
  }
}
Project.findById(req.params._id, function(err, foundProject){
  if(err){
    console.log('Error finding project');
    console.log(err);
  } else {
      nextProject.exec(function(err, next){
        if(err){
          console.log('err');
          console.log(err);
        } else {
          prevProject.exec(function(err, prev){
            if(err){
              console.log('err');
              console.log(err);
            } else {
              console.log(prev[0].title);
              console.log('==============================================');
              console.log(foundProject);
              console.log('==============================================');
              console.log(next[0].title);
              res.render('project', {project: foundProject, nextProject: next[0], prevProject: prev[0]});
            }
          });
        }
      });
    }
});

第二次编辑,包含更多无效的代码:

app.get('/projects/:_id', function(req, res){
  var nextProject = Project.find({_id: {$gt: req.params._id}}).sort({_id: 1 }).limit(1)
  var prevProject = Project.find({_id: {$lt: req.params._id}}).sort({_id: -1 }).limit(1)
  // find the project for the clicked link
  Project.findById(req.params._id, function(err, foundProject){
    if(err){ // handle any errors
      console.log('Error finding project');
      console.log(err);
    } else {
      nextProject.exec(function(err, next){ // if no errors, execute the query object for the next project
    if(err){ // handle any errors
      console.log('Error getting next project');
      console.log(err);
    } else if(next){ // if next has a value...
      prevProject.exec(function(err, prev){ // ... execute the query object for the previous project
        if(err){  // handle any errors
          console.log('error getting previous project');
          console.log(err);
        } else if(prev){ // if previous has a value...
          console.log('prev and next have a value');
          console.log('============================foundProject============================');
          console.log(foundProject);
          console.log('============================prevProject============================');
          console.log(prev);
          console.log('============================nextProject============================');
          console.log(next);
          res.render('project', {project: foundProject, nextProject: next[0], prevProject: prev[0]});//... render the project page with current project, next project and previous project
        } else if(prev){ // if previous doesn't have a value...
          var prevProject = Project.find().sort({_id: -1}).limit(1);//... get a query object for the last document in the database
          prevProject.exec(function(err, prev){ // execute the query object for the last document
            if(err){ // handle any errors
              console.log('error getting last document');
              console.log(err);
            } else { // with no errors...
              console.log('next has a value, but previous does not. Gone to last project');
              res.render('project', {project: foundProject, nextProject: next[0], prevProject: prev[0]}); // ... render the page
            }
          })
        }
      })
    } else if(next){ //if next doesn't have a value...
      var nextProject = Project.find().sort({_id: 1 }).limit(1);//get a query object for the first document
      nextProject.exec(function(err, next){ // execute the query object
        if(err){
          console.log('error getting first project');
          console.log(err);
        } else { // with no errors...
          console.log('previous has a value, but next does not. Gone to first project');
          res.render('project', {project: foundProject, nextProject: next[0], prevProject: prev[0]});//render the page
        }
      });
    }
  });
}

}); });

【问题讨论】:

    标签: javascript mongodb mongoose database


    【解决方案1】:

    你说:

    链接也存储在数据库中

    (1) 为每个项目存储链接

    nextprevious 链接可以存储在 project 中,然后您无需在数据库中获取任何内容来显示它们。

    它确实要求您在删除链接项目时更新项目的链接。但这可能不会经常发生?


    (2) next 失败时查找第一个文档

    否则,使用您当前的代码,如果 nextProject 没有返回任何内容,您可以这样做:

    nextProject = Project.find().sort({_id: 1 }).limit(1).
    

    (3) 使用聚合

    如果您知道第一个文档的 _id,则可以使用聚合:

    $ Project.aggregate([{
                 $match: {
                   $or: [{_id: {$gt: req.params._id}}, 
                         {_id: lowerId} ] }}, 
                 {$sort: {_id: -1}}, 
                 {$limit: 1}
             ])
    

    但如果你知道第一个文件,我会改为:

    • 将第一个文档保存在内存中;
    • 尝试加载下一个;
    • 如果失败,请获取第一个文档。

    【讨论】:

    • 嘿,非常感谢亚历克斯!您的 sn-p 可以获取第一个条目,但是如果有一个条目,我不知道如何获取下一个条目,如果没有,则获取第一个条目...我对 MongoDB 很陌生,并且我不确定语法。我一直在尝试这样的事情:var nextProject = Project.find({ $or: [ {<expression 1>}, { <expression 2> } ] } ) 但也许我找错了树……?
    • 我只执行第一个查询,如果结果为空,则执行第二个。
    • 更新了一个聚合示例。但是,如果您已经知道第一个文档的 ID,我只能使其工作。如果是这种情况,您可以轻松地将第一个文档保存在内存中。
    • 非常感谢您对这个 Alex 的帮助!我认为选项 2 最适合我的情况。我试图实现它,但 nextProject 以未定义的形式返回。我将使用新代码更新我原来的问题...
    • 哪一行返回 undefined ? “var nextProject = Project.find().sort({_id: 1 }).limit(1);”这个?
    猜你喜欢
    • 2018-08-20
    • 1970-01-01
    • 2015-08-14
    • 2021-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-24
    相关资源
    最近更新 更多