ran*_*its 33 pagination mongodb casbah mongodb-query aggregation-framework
我有兴趣优化我正在使用MongoDB的"分页"解决方案.我的问题很直接.我通常会限制使用该limit()功能返回的文档数量.这迫使我发出一个没有该limit()函数的冗余查询,以便我也可以捕获查询中的文档总数,这样我就可以将其传递给客户端,让他们知道他们必须发出额外的请求.检索其余文件.
有没有办法将其压缩为1个查询?获取文档总数但同时仅使用limit()?检索子集?是否有不同的方式来思考这个问题,而不是接近它?
Ash*_*shh 23
Mongodb 3.4引入了$facet聚合
它在同一组输入文档的单个阶段中处理多个聚合管道。
使用$facet和$group可以找到的文档,$limit并可以获得总数。
您可以在mongodb 3.4中使用以下聚合
db.collection.aggregate([
{ "$facet": {
"totalData": [
{ "$match": { }},
{ "$skip": 10 },
{ "$limit": 10 }
],
"totalCount": [
{ "$group": {
"_id": null,
"count": { "$sum": 1 }
}}
]
}}
])
Run Code Online (Sandbox Code Playgroud)
即使您可以使用 $countmongodb 3.6中引入的聚合。
您可以在mongodb 3.6中使用以下聚合
db.collection.aggregate([
{ "$facet": {
"totalData": [
{ "$match": { }},
{ "$skip": 10 },
{ "$limit": 10 }
],
"totalCount": [
{ "$count": "count" }
]
}}
])
Run Code Online (Sandbox Code Playgroud)
hei*_*nob 22
不,没有其他办法.两个查询 - 一个用于计数 - 一个用于限制.或者您必须使用其他数据库.例如Apache Solr就像您想要的那样工作.每个查询都有限制并返回totalCount.
dev*_*dev 12
MongoDB 允许您使用,cursor.count()即使您通过limit()或skip().
假设您有db.collection10 个项目。
你可以做:
async function getQuery() {
let query = await db.collection.find({}).skip(5).limit(5); // returns last 5 items in db
let countTotal = await query.count() // returns 10-- will not take `skip` or `limit` into consideration
let countWithConstraints = await query.count(true) // returns 5 -- will take into consideration `skip` and `limit`
return { query, countTotal }
}
Run Code Online (Sandbox Code Playgroud)
时代变了,我相信你能达到什么OP是通过聚合与要求$sort,$group和$project.对于我的系统,我还需要从我的users收藏中获取一些用户信息.希望这也可以回答任何问题.下面是一个聚合管道.最后三个对象(排序,组和项目)处理总计数,然后提供分页功能.
db.posts.aggregate([
{ $match: { public: true },
{ $lookup: {
from: 'users',
localField: 'userId',
foreignField: 'userId',
as: 'userInfo'
} },
{ $project: {
postId: 1,
title: 1,
description: 1
updated: 1,
userInfo: {
$let: {
vars: {
firstUser: {
$arrayElemAt: ['$userInfo', 0]
}
},
in: {
username: '$$firstUser.username'
}
}
}
} },
{ $sort: { updated: -1 } },
{ $group: {
_id: null,
postCount: { $sum: 1 },
posts: {
$push: '$$ROOT'
}
} },
{ $project: {
_id: 0,
postCount: 1,
posts: {
$slice: [
'$posts',
currentPage ? (currentPage - 1) * RESULTS_PER_PAGE : 0,
RESULTS_PER_PAGE
]
}
} }
])
Run Code Online (Sandbox Code Playgroud)
小智 7
在Mongodb 3.4中有一种方法:$ facet
你可以做
db.collection.aggregate([
{
$facet: {
data: [{ $match: {} }],
total: { $count: 'total' }
}
}
])
Run Code Online (Sandbox Code Playgroud)
那么你将能够同时运行两个聚合
以下是使用MongoDB 3.4+(使用 Mongoose)执行此操作的方法$facets。此示例$count根据匹配后的文档返回 a 。
const facetedPipeline = [{
"$match": { "dateCreated": { $gte: new Date('2021-01-01') } },
"$project": { 'exclude.some.field': 0 },
},
{
"$facet": {
"data": [
{ "$skip": 10 },
{ "$limit": 10 }
],
"pagination": [
{ "$count": "total" }
]
}
}
];
const results = await Model.aggregate(facetedPipeline);
Run Code Online (Sandbox Code Playgroud)
此模式对于获取从 REST API 返回的分页信息很有用。
小智 6
默认情况下,count() 方法会忽略 cursor.skip() 和 cursor.limit() 的影响(MongoDB 文档)
由于count方法排除了limit和skip的影响,可以使用cursor.count()得到总计数
const cursor = await database.collection(collectionName).find(query).skip(offset).limit(limit)
return {
data: await cursor.toArray(),
count: await cursor.count() // this will give count of all the documents before .skip() and limit()
};
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
21515 次 |
| 最近记录: |