Mongoose获得一个随机元素,除了一个

时间:2017-09-25 08:50:47

标签: node.js mongodb random mongoose

我在mongodb中收集了一些文章。我选择了一篇我要渲染的文章,我想要随机选择另外两篇文章。我想在我的收藏中挑选两篇不一样的文章,而不是我之前选择的文章。 几个小时一直在解决这个问题,寻找一个解决方案,但只找到了如何随机选择一个元素,但除了一个... ...

以下是我现在所拥有的:

article.find({}, function(err, articles{   
    var articleChosen = articles.filter(selectArticleUrl, articleUrl)[0];
    article.find({})
    .lean()
    .distinct("_id")
    .exec(function(err, arrayIds){  
      var articleChosenIndex = arrayIds.indexOf(articleChosen._id);
      arrayIds.splice(articleChosenIndex, 1);
      chooseRdmArticle(arrayIds, function(articleRdm1Id){
        var articleRmd1 = articles.filter(selectArticleId, articleRdm1Id)[0];
        var articleRdm1Index = arrayIds.indexOf(articleRdm1Id);
        arrayIds.splice(articleRdm1Index, 1);
        chooseRdmArticle(arrayIds, function(articleRdm2Id){
          var articleRmd2 = articles.filter(selectArticleId, articleRdm2Id)[0];
          // do stuff with articleChosen, articleRmd1 and articleRmd2
        })
      })
    })
  })

选择rdm文章的函数是:

function chooseRdmArticle(articles, callback){
  var min = Math.ceil(0);
  var max = Math.floor(articles.length);
  var rdm = Math.floor(Math.random() * (max - min)) + min;
  callback(articles[rdm])
}

以及从其网址中选择文章的功能是:

function selectArticleUrl(element){
  return element.url == this
}

我的想法是处理包含所有ObjectId(此处为arrayIds)的数组,在删除articleChosen id后随机选择两个ID。但我明白arrayIds.indexOf(articleRdm1Id);无法工作,因为ObjectIds不是字符串...有没有找到我想要的Id索引的方法?或者更好的主意?

非常感谢!

2 个答案:

答案 0 :(得分:0)

有mongodb命令$sample,它会随机读取文件。

文档中的示例

  

db.users.aggregate([{$ sample:{size:3}}])

答案 1 :(得分:0)

运行两个查询,其中第一个获取所选文档,另一个使用聚合框架运行带有 $sample 运算符的管道,以从集合中返回2个随机文档,但所选一。

以下查询使用Mongoose的内置Promises来证明这一点:

let chosenArticle = article.find({ "url": articleUrl }).exec();
let randomArticles = article.aggregate([
    { "$match": { "url": { "$ne": articleUrl } } },
    { "$sample": { "size": 2 } }
]).exec();

Promise.all([chosenArticle, randomArticles]).then(articles => {
    console.log(articles);
});