Node.js 如何在嵌套对象属性上使用MongoDB$ne
我有一个节点API,它通过mongoose连接到mongoDB。我正在创建一个高级结果中间件,它可以基于Brad Traversy课程进行选择、筛选、排序、分页等。这一切都很好 我正在修改课程中的代码,以便能够使用$ne(不等于)操作符,并且我希望能够获得一个不等于模型的嵌套属性(用户id)的模型。我将此用于浏览功能,以查看内容列表,但我不想向用户显示他们自己的内容。我很难弄清楚如何访问id属性 *********************更新********************* 似乎我读过的所有文档都建议像这样编写const injected:Node.js 如何在嵌套对象属性上使用MongoDB$ne,node.js,mongodb,mongoose,Node.js,Mongodb,Mongoose,我有一个节点API,它通过mongoose连接到mongoDB。我正在创建一个高级结果中间件,它可以基于Brad Traversy课程进行选择、筛选、排序、分页等。这一切都很好 我正在修改课程中的代码,以便能够使用$ne(不等于)操作符,并且我希望能够获得一个不等于模型的嵌套属性(用户id)的模型。我将此用于浏览功能,以查看内容列表,但我不想向用户显示他们自己的内容。我很难弄清楚如何访问id属性 *********************更新********************* 似乎我读过
const injected = {
'user._id': { "$ne": req.user.id }
};
const injected = {
access: { "$ne": "public" }
};
{
name: 'Awesome post',
access: 'public',
user: {
_id: '2425635463456241345', // property I want to access
}
}
但由于某些原因,它不起作用。我可以查询仅为普通字符串值的顶级属性,如下所示:
const injected = {
'user._id': { "$ne": req.user.id }
};
const injected = {
access: { "$ne": "public" }
};
{
name: 'Awesome post',
access: 'public',
user: {
_id: '2425635463456241345', // property I want to access
}
}
但不是对象上的属性。有人知道为什么吗?是因为我要查询的属性是id吗?我也试过:
const injected = {
'user._id': { "$ne": mongoose.Types.ObjectId(req.user.id) }
};
这也不起作用
因此,模型如下所示:
const injected = {
'user._id': { "$ne": req.user.id }
};
const injected = {
access: { "$ne": "public" }
};
{
name: 'Awesome post',
access: 'public',
user: {
_id: '2425635463456241345', // property I want to access
}
}
然后,实际的advanced results中间件看起来像这样,它是我尝试访问id的“注入”对象。在课程中,brad使用此语法使用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;
const advancedResults=(模型,填充)=>async(请求,恢复,下一步)=>{
让查询;
注入常数={
访问:'公共',
'user.\u id[ne]':req.user.id,//我认为user.\u id[ne]不正确
};
}
//复制请求查询
const reqQuery={…req.query,…injected};
log('injected:',injected);
//要排除的字段
常量removeFields=[“选择”、“排序”、“页面”、“限制”];
//在removeFields上循环并从reqQuery中删除它们
forEach(param=>deleteReqQuery[param]);
//创建查询字符串
让queryStr=JSON.stringify(reqQuery);
//创建运营商($gt、$gte等)
queryStr=queryStr.replace(/\b(gt|gte|lt|lte|in | ne)\b/g,match=>“$${match}”);
//查找资源并删除版本
query=model.find(JSON.parse(queryStr)).select('-\uv');
//选择字段
if(请求查询选择){
const fields=req.query.select.split(',').join(“”);
query=query.select(字段);
}
//分类
if(请求查询排序){
const sortBy=req.query.sort.split(‘,’).join(‘);
query=query.sort(sortBy);
}否则{
query=query.sort('-createdAt');
}
//分页
const page=parseInt(req.query.page,10)| 1;
const limit=parseInt(req.query.limit,10)| 25;
常量startIndex=(第1页)*限制;
const endIndex=页面*限制;
const total=await model.countDocuments(JSON.parse(queryStr));
query=query.skip(startIndex).limit(limit);
如果(填充){
query=query.populate(填充);
}
//执行查询
const results=等待查询;
//分页结果
常数分页={};
如果(endIndex<总计){
分页。下一步={
页码:第+1页,
极限,
};
}
如果(起始索引>0){
pagination.prev={
第页:第1页,
极限,
};
}
res.advancedResults={
成功:没错,
计数:results.length,
标页码
数据:结果,
};
next();
};
module.exports=高级结果;
回答您关于如何使用$ne
的问题:
其用途如下:
“字段”:{
“$ne”:你的价值
}
您的查询应该是这样的:
“用户id”:{
“$ne”:req.user.id
}
范例
$ne
操作员将返回字段值与给定值不匹配的所有文档
正如您所做的,要访问嵌套字段,必须使用点表示法
另外,为了确保它工作,如果您的模式将\u id
定义为ObjectId
,可能需要将req.user.id
解析为ObjectId
但是,如果在您的模式中有一个字符串,那么应该可以工作
因此,请尝试(根本不测试):
const注入={
'user._id':{“$ne”:req.user.id}
};
嘿,谢谢!但它似乎不起作用;我仍然从登录的用户那里获得结果。我还尝试用硬编码字符串替换req.user.id。我也尝试过这样做:'user.\u id':{ne:new mongoose.Types.ObjectId(req.user.id)},但运气不好。(我从ne中删除了$,因为如果你注意到我的代码稍后会添加它。你能发布你的req
对象吗?整个请求还是仅仅是查询?在我创建操作符后,queryStr的控制台日志给出了(这里的id是假的):queryStr:{“access”:“public”,“user.\u id:{“$ne”:“5t845tu495t83r3iuf3rf”}您的查询正在寻找访问权限:“public”
,但您的模型只有名称
和用户
字段。我使用了名称:“Awesome post”
而不是“access”:“public”
,它可以工作。如果您的数据或模型已更改,请编辑OP,我将再次执行。