Исключение нулевого указателя - это индикатор того, что вы используете объект, не инициализируя его.
Например, ниже - класс ученика, который будет использовать его в нашем коде.
public class Student {
private int id;
public int getId() {
return this.id;
}
public setId(int newId) {
this.id = newId;
}
}
Приведенный ниже код дает вам исключение с нулевым указателем.
public class School {
Student obj_Student;
public School() {
try {
obj_Student.getId();
}
catch(Exception e) {
System.out.println("Null Pointer ");
}
}
}
Поскольку вы используете Obj_Student
, но вы забыли инициализировать его, как в правильном коде, показанном ниже:
public class School {
Student obj_Student;
public School() {
try {
obj_Student = new Student();
obj_Student.setId(12);
obj_Student.getId();
}
catch(Exception e) {
System.out.println("Null Pointer ");
}
}
}
Нет, другого пути нет. Два запроса - один для подсчета - один с лимитом. Или вам нужно использовать другую базу данных. 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
});
});