Исключение нулевого указателя генерируется, когда приложение пытается использовать null в случае, когда требуется объект. К ним относятся:
null
. null
. null
, как если бы это был массив. null
, как если бы это был массив. null
как будто это было значение Throwable. Приложения должны бросать экземпляры этого класса, чтобы указать на другие незаконные использования объекта null
.
Ссылка: http://docs.oracle.com/javase/8/docs/api/java/lang/NullPointerException.html
Нет, другого пути нет. Два запроса - один для подсчета - один с лимитом. Или вам нужно использовать другую базу данных. Apache Solr, например, работает так, как вы хотите. Каждый запрос там ограничен и возвращает totalCount.
можно получить , чтобы получить общий размер результата без эффекта Согласно документации вы можете даже контролировать, учитывается ли ограничение / разбиение на страницы при вызове Изменить: в отличие от того, что написано в другом месте - документы четко указывают, что «Операция не выполняет запрос, а вместо этого подсчитывает результаты который будет возвращен запросом «. Который - из моего понимания - означает, что выполняется только один запрос. Пример: limit()
, используя count()
, как здесь указано: Ограничение результатов в MongoDB, но все еще получение полного счета? count()
: https://docs.mongodb.com/manual/reference/method/ cursor.count / # cursor.count > db.createCollection("test")
{ "ok" : 1 }
> db.test.insert([{name: "first"}, {name: "second"}, {name: "third"},
{name: "forth"}, {name: "fifth"}])
BulkWriteResult({
"writeErrors" : [ ],
"writeConcernErrors" : [ ],
"nInserted" : 5,
"nUpserted" : 0,
"nMatched" : 0,
"nModified" : 0,
"nRemoved" : 0,
"upserted" : [ ]
})
> db.test.find()
{ "_id" : ObjectId("58ff00918f5e60ff211521c5"), "name" : "first" }
{ "_id" : ObjectId("58ff00918f5e60ff211521c6"), "name" : "second" }
{ "_id" : ObjectId("58ff00918f5e60ff211521c7"), "name" : "third" }
{ "_id" : ObjectId("58ff00918f5e60ff211521c8"), "name" : "forth" }
{ "_id" : ObjectId("58ff00918f5e60ff211521c9"), "name" : "fifth" }
> db.test.count()
5
> var result = db.test.find().limit(3)
> result
{ "_id" : ObjectId("58ff00918f5e60ff211521c5"), "name" : "first" }
{ "_id" : ObjectId("58ff00918f5e60ff211521c6"), "name" : "second" }
{ "_id" : ObjectId("58ff00918f5e60ff211521c7"), "name" : "third" }
> result.count()
5 (total result size of the query without limit)
> result.count(1)
3 (result size with limit(3) taken into account)
count()
работает только с find()
и, следовательно, не помогает с запросами aggregate
– Felipe
13 February 2018 в 06:01
MongoDB позволяет вам использовать cursor.count()
даже при передаче limit()
или skip()
.
Допустим, у вас есть db.collection
с 10 элементами.
Вы может сделать:
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 }
}
есть способ в Mongodb 3.4: $ facet
вы можете сделать
db.collection.aggregate([
{
$facet: {
data: [{ $match: {} }],
total: { $count: 'total' }
}
}
])
, тогда вы сможете одновременно запустить два агрегата
Все зависит от опыта разбивки на страницы, который вам нужен, независимо от того, нужно ли вам выполнять два запроса.
Вам нужно перечислить каждую страницу или даже целый ряд страниц? Кто-нибудь даже идет на страницу 1051 - концептуально, что это значит?
У вас много UX по шаблонам разбивки на страницы - Избегайте болей разбивки на страницы , охватывая различные типы разбивки на страницы и их сценарии, и многим не нужен запрос подсчета, чтобы узнать, есть ли следующую страницу. Например, если вы отобразите 10 элементов на странице, и вы ограничены до 13 - вы узнаете, есть ли другая страница ..
Попробуйте следующее:
cursor.count (false, function (err, total) {console.log ("total", total)})
blockquote>core.db.users.find(query, {}, {skip:0, limit:1}, function(err, cursor){ if(err) return callback(err); cursor.toArray(function(err, items){ if(err) return callback(err); cursor.count(false, function(err, total){ if(err) return callback(err); console.log("cursor", total) callback(null, {items: items, total:total}) }) }) })
Времена изменились, и я считаю, что вы можете достичь того, что спрашивает 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
]
}
} }
])
Вы можете сделать это в одном запросе. Сначала вы запускаете счетчик и внутри него запускаете функцию limit ().
В Node.js и Express.js вам придется использовать его так, чтобы использовать функцию «count» с результатом «toArray».
var curFind = db.collection('tasks').find({query});
Затем вы можете запустить две функции после этого, как это (один вложен в другой)
curFind.count(function (e, count) {
// Use count here
curFind.skip(0).limit(10).toArray(function(err, result) {
// Use result here and count here
});
});