Mongodb从集合中选择随机查询,除了少数ID

时间:2019-10-29 18:02:21

标签: 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之外的另一个用户。

1 个答案:

答案 0 :(得分:1)

替代您的方法:

main

在聊天集合中使用诸如(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 } )之类的复合索引。 应该对大型集合(因为命中相同的可能性较低)以及小型集合都可以很好地工作,因为集合应该适合内存并且易于从磁盘读取。