【发布时间】:2021-02-25 07:59:37
【问题描述】:
我有一个通过 mongoose 连接到 mongoDB 的节点 API。我正在创建一个基于 Brad Traversy 课程Node.js API Masterclass With Express & MongoDB 的高级结果中间件,该中间件支持选择、过滤、排序、分页等。这一切都很好。
我正在修改课程中的代码,以便能够使用 $ne(不等于)运算符,并且我希望能够获得一个不等于模型的嵌套属性(用户 ID)的模型。我将其用于探索功能以查看事物列表,但我不想向用户展示他们自己的事物。我无法弄清楚如何访问 id 属性。
********************* 更新 *********************
似乎我读过的所有文档都建议像这样编写 const 注入:
const injected = {
'user._id': { "$ne": req.user.id }
};
但由于某种原因它无法正常工作。我可以像这样查询只是普通字符串值的顶级属性:
const injected = {
access: { "$ne": "public" }
};
但不是对象的属性。有谁知道为什么?是不是因为我要查询的属性是一个id?我也试过:
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;
【问题讨论】: