下午好。我有“有效”的代码,但我担心它可能是“愚蠢的”。
我最近添加了一条路由来处理针对我的 mongodb 的正则表达式搜索。发送请求的客户端非常有限,只能处理 < 2K body size. So I needed to add pagination to break up a large return into multiple http requests...
重要的是,我真的不知道我不知道什么,我的解决方案很可能建立在无知之上。我担心可扩展性和冗余。为了获取返回查询的计数,我运行了两次查询。一次获取所有记录的计数,再次对其进行分页。然后,客户端可以循环执行其他调用以获取所需的所有数据。每次击中仍然需要两次运行......愚蠢。
我的搜索围绕这些问题进行,坦率地说,有很多争论超出了我的理解范围。聚合?水桶?缓存查询?
在编写下面的路线时,感觉我应该能够对初始的 TotalData .find 进行分页,但无法弄清楚如何对这些结果进行分页。所以我只是用分页再次运行它。
无论如何,让我知道我误入歧途的地方:
//Regex info is passed in the body
//mmValue string containing the fields of a document I want to retrieve ex: -_id mmKey mmValue updateAt
//mmPage return this page, defaults to 1
//mmLimit limit documents returned
//mmField what field in the document to apply the regex against ex: updatedAt or mmKey or _id
//mmRegex the regular expression to applied to mmField ex: Findme
router.post('/mmRegex', async (req, res) => {
try {
const returnData = req.body.mmValue
const page = parseInt(req.body.mmPage)
const limit = parseInt(req.body.mmLimit)
const map = new Map([[ req.body.mmField , new RegExp(req.body.mmRegex,req.body.mmRegexOp)]])
const rquery = Object.fromEntries(map)
const totalData = await Model.find(rquery).select(returnData)
const pageData = await Model.find(rquery).skip((page -1)*limit).limit(limit).select(returnData)
const totalPages = Math.ceil(totalData.length / limit)
console.log(" RegEx: ",rquery, " count: ",totalData.length);
const results = {
count: totalData.length,
cPage: page,
tPage: totalPages,
pageData
}
res.send(results)
}
catch (error){
console.log(" RegEx: ",rquery," msg: ", error.message);
res.status(500).json({ status: "failed", message: error.message })
}
})
这确实返回了我需要的数据,但可能是以一种愚蠢的方式 谢谢您的时间!
您可以使用
countDocuments
功能检索文档计数。
const count = await Model.countDocuments()
也可以使用
facet
在单个查询中完成相同的操作。您的查询是
const data = await Model
.aggregate([
{
$facet: {
total: [
{
$count: "count",
},
],
docs: [
{
$match: {},
},
{
$skip: skipValue,
},
{
$limit: limitValue,
},
],
},
},
])