我认为确保用户每次只看到独特的用户的唯一方法是存储已经被看过的用户列表。即使在你链接的
RAND
示例中,也有可能与先前的用户列表相交,因为
RAND
不一定会排除以前返回的用户。
随机抽样
如果你想采用随机抽样,可以考虑使用从MongoDB中随机选择记录,该方法建议使用聚合和$sample
操作符。具体实现如下:
const {
MongoClient
} = require("mongodb");
const
DB_NAME = "weather",
COLLECTION_NAME = "readings",
MONGO_DOMAIN = "localhost",
MONGO_PORT = "32768",
MONGO_URL = `mongodb://${MONGO_DOMAIN}:${MONGO_PORT}`;
(async function () {
const client = await MongoClient.connect(MONGO_URL),
db = await client.db(DB_NAME),
collection = await db.collection(COLLECTION_NAME);
const randomDocs = await collection
.aggregate([{
$sample: {
size: 5
}
}])
.map(doc => {
return {
id: doc._id,
temperature: doc.main.temp
}
});
randomDocs.forEach(doc => console.log(`ID: ${doc.id} | Temperature: ${doc.temperature}`));
client.close();
}());
以前用户的缓存
如果您选择维护先前查看过的用户列表,可以编写一个使用$nin
过滤器实现的方案,并存储以前查看过的用户的_id
。
以下是一个示例,使用我拥有的天气数据库,每次返回5个条目,直到所有条目都已打印:
const {
MongoClient
} = require("mongodb");
const
DB_NAME = "weather",
COLLECTION_NAME = "readings",
MONGO_DOMAIN = "localhost",
MONGO_PORT = "32768",
MONGO_URL = `mongodb://${MONGO_DOMAIN}:${MONGO_PORT}`;
(async function () {
const client = await MongoClient.connect(MONGO_URL),
db = await client.db(DB_NAME),
collection = await db.collection(COLLECTION_NAME);
let previousEntries = [],
empty = false;
while (!empty) {
const findFilter = {};
if (previousEntries.length) {
findFilter._id = {
$nin: previousEntries
}
}
const docs = await collection
.find(findFilter, {
limit: 5,
projection: {
main: 1
}
})
.map(doc => {
return {
id: doc._id,
temperature: doc.main.temp
}
})
.toArray();
previousEntries = previousEntries.concat(docs.map(doc => doc.id));
console.log(docs.length);
empty = !docs.length;
docs.forEach(doc => console.log(`ID: ${doc.id} | Temperature: ${doc.temperature}`));
}
client.close();
}());