Node.js 如何在嵌套对象属性上使用MongoDB$ne

Node.js 如何在嵌套对象属性上使用MongoDB$ne,node.js,mongodb,mongoose,Node.js,Mongodb,Mongoose,我有一个节点API,它通过mongoose连接到mongoDB。我正在创建一个高级结果中间件,它可以基于Brad Traversy课程进行选择、筛选、排序、分页等。这一切都很好 我正在修改课程中的代码,以便能够使用$ne(不等于)操作符,并且我希望能够获得一个不等于模型的嵌套属性(用户id)的模型。我将此用于浏览功能,以查看内容列表,但我不想向用户显示他们自己的内容。我很难弄清楚如何访问id属性 *********************更新********************* 似乎我读过

我有一个节点API,它通过mongoose连接到mongoDB。我正在创建一个高级结果中间件,它可以基于Brad Traversy课程进行选择、筛选、排序、分页等。这一切都很好

我正在修改课程中的代码,以便能够使用$ne(不等于)操作符,并且我希望能够获得一个不等于模型的嵌套属性(用户id)的模型。我将此用于浏览功能,以查看内容列表,但我不想向用户显示他们自己的内容。我很难弄清楚如何访问id属性

*********************更新*********************

似乎我读过的所有文档都建议像这样编写const injected:

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,我将再次执行。