#node.js #mongodb #mongoose
#node.js #mongodb #мангуст
Вопрос:
У меня есть API узла, который подключается к MongoDB через mongoose. Я создаю промежуточное ПО для расширенных результатов, которое позволяет выбирать, фильтровать, сортировать, разбивать на страницы и т. Д. На основе курса Brad Traversy Node.js Мастер-класс по API с помощью Express и MongoDB. Это все хорошо.
Я адаптирую код из курса, чтобы иметь возможность использовать оператор $ ne (not equal), и я хочу иметь возможность получить модель, которая не равна вложенному свойству (идентификатору пользователя) модели. Я использую это для функции изучения, чтобы увидеть список вещей, но я не хочу показывать пользователю их собственные вещи. У меня возникли проблемы с пониманием того, как получить доступ к свойству id.
********************* ОБНОВИТЬ *********************
Кажется, вся документация, которую я прочитал, рекомендует писать const, введенный следующим образом:
const injected = {
'user._id': { "$ne": req.user.id }
};
но по какой-то причине он не работает. Я могу запрашивать свойства верхнего уровня, которые представляют собой простое строковое значение, подобное этому:
const injected = {
access: { "$ne": "public" }
};
но не свойство объекта. Кто-нибудь знает, почему? Это потому, что свойство, которое я хочу запросить, является идентификатором? Я также пробовал:
const injected = {
'user._id': { "$ne": mongoose.Types.ObjectId(req.user.id) }
};
который также не работает…
Итак, модель выглядит следующим образом:
{
name: 'Awesome post',
access: 'public',
user: {
_id: '2425635463456241345', // property I want to access
}
}
тогда фактическое промежуточное программное обеспечение с расширенными результатами выглядит следующим образом, и это «внедренный» объект, к которому я пытаюсь получить доступ id. В курсе брэд использует этот синтаксис для использования lte (/?averageCost [lte] = 10000), но я не получаю никаких результатов с моим ne. Кто-нибудь может мне здесь помочь?
const advancedResults = (model, populate) => async (req, res, next) => {
let query;
const injected = {
access: 'public',
'user._id[ne]': req.user.id, // I don't think user._id[ne] is correct
};
}
// Copy req.query
const reqQuery = { ...req.query, ...injected };
console.log('injected: ', injected);
// Fields to exclude
const removeFields = ['select', 'sort', 'page', 'limit'];
// Loop over removeFields and delete them from reqQuery
removeFields.forEach(param => delete reqQuery[param]);
// Create query string
let queryStr = JSON.stringify(reqQuery);
// Create operators ($gt, $gte, etc)
queryStr = queryStr.replace(/b(gt|gte|lt|lte|in|ne)b/g, match => `$${match}`);
// Finding resource and remove version
query = model.find(JSON.parse(queryStr)).select('-__v');
// Select Fields
if (req.query.select) {
const fields = req.query.select.split(',').join(' ');
query = query.select(fields);
}
// Sort
if (req.query.sort) {
const sortBy = req.query.sort.split(',').join(' ');
query = query.sort(sortBy);
} else {
query = query.sort('-createdAt');
}
// Pagination
const page = parseInt(req.query.page, 10) || 1;
const limit = parseInt(req.query.limit, 10) || 25;
const startIndex = (page - 1) * limit;
const endIndex = page * limit;
const total = await model.countDocuments(JSON.parse(queryStr));
query = query.skip(startIndex).limit(limit);
if (populate) {
query = query.populate(populate);
}
// Executing query
const results = await query;
// Pagination result
const pagination = {};
if (endIndex < total) {
pagination.next = {
page: page 1,
limit,
};
}
if (startIndex > 0) {
pagination.prev = {
page: page - 1,
limit,
};
}
res.advancedResults = {
success: true,
count: results.length,
pagination,
data: results,
};
next();
};
module.exports = advancedResults;
Ответ №1:
Отвечая на ваш вопрос о том, как использовать $ne
:
Использование $ne
заключается в следующем:
"field":{
"$ne": yourValue
}
В вашем запросе должно быть:
"user._id": {
"$ne": req.user.id
}
Пример здесь
$ne
оператор вернет весь документ, в котором значение поля не совпадает с заданным значением.
Как вы уже сделали, для доступа к вложенному полю необходимо использовать точечную нотацию.
Кроме того, чтобы убедиться, что это работает, если ваша схема определяет _id
как ObjectId
, возможно, необходимо проанализировать req.user.id
ObjectId
.
Но если в вашей схеме есть строка, то она должна работать.
Так что попробуйте (вообще не тестировалось):
const injected = {
'user._id': { "$ne": req.user.id }
};
Комментарии:
1. Привет, спасибо! Похоже, это не работает; Я все еще получаю результаты от вошедшего в систему пользователя. Я также пытался заменить req.user.id с жестко закодированной строкой.
2. Я также пробовал это так: ‘user._id’: { ne: новый мангуст. Типы. ObjectId(req.user.id ) }, но безуспешно. (Я удалил $ из ne, потому что, если вы заметили, мой код добавит это позже.
3. Можете ли вы опубликовать свой
req
объект?4. Весь запрос или только запрос? Консольный журнал запроса после создания операторов выдает (идентификатор здесь поддельный): queryStr: {«access»:»public»,»user._id»: {«$ne»:»5t845tu495t83r3iuf3rf»}}
5. Ваш запрос ищет
access:"public"
, но в вашей модели есть только поляname
иuser
. Я использовалname:"Awesome post"
вместо"access":"public"
, и это работает. Если ваши данные или ваша модель изменились, отредактируйте OP, и я снова выполню.