node.js - Mongodb 从集合中选择随机查询,除了少数 id

标签 node.js mongodb mongoose

我有一个“用户”和“聊天”集合

用户方案如下:

username: {
type: String,
unique: true, required: true
}

以及聊天方案:

from: {
       type: Schema.Types.ObjectId,
       required: true
},
to:{
       type: Schema.Types.ObjectId,
       required: true
},
content:{
       type:String,
       required:true
}

我的目的是在一个用户和另一个随机选择的用户之间开始聊天。

到目前为止,我的代码用于选择随机用户:

User.aggregate([
        { "$match": { "_id": { "$ne": mongoose.Types.ObjectId(from_id) }}},
        {$sample: {size: 1}}]

我正在使用 "$ne": mongoose.Types.ObjectId(from_id) 因此它不会选择同一用户。

我想要实现的是选择除同一用户(已完成)之外的用户以及第一个用户已经与之聊天的人之外的用户。 就像如果 user1 和 user2 之间已经存在聊天一样,代码必须选择除 user2 之外的另一个用户。

最佳答案

作为您的方法的替代方法:

const count = model.estimatedDocumentCount()
if (count === 2) {
  throe new Error('Not possible')
}

let newUser = null
let i = 0
while(true) {
  const random = Math.random() * count
  newUser = await model.findOne({_id: {$ne: fromId}}).skip(random).exec()
  if (!(await chatModel.findOne({$or: [{from: fromId, to: newUser._id}, {to: fromId, from: newUser._id}]}, {_id: 1}).exec())) {
     break
  }
  if (i === 1000) {
    throw new Error('Ah well not today') // can come up with some alternative strategy
  }
  ++i
}

在聊天集合上使用复合索引,例如 ({from: 1, to: 1})。 应该在大型集合上很好地工作(因为命中相同的概率很低),并且在小型集合上工作得很好,因为集合应该适合内存并且易于从磁盘读取。

关于node.js - Mongodb 从集合中选择随机查询,除了少数 id,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58613098/

相关文章:

node.js - 在 Node.JS 中使用 Passport 注册(注册)

javascript - Reactjs 源图

node.js - 对未知 URL 数量的异步 GET 请求

mongodb - 通过 mongodb 中的字段与授权 token 授权资源(例如图像)访问?

javascript - bcrypt-nodejs 比较方法每次都返回 false

node.js - 2023年如何在nodejs中使用gmail发送电子邮件?

javascript - 在 mongoDB 中获取相邻文档之间的差异

c# - 在 MongoDB 中自动递增序列字段时插入文档

node.js - Mongoose findbyid() 返回 null

node.js - 用于模式定义的 Mongoose 或 MongoDB?