【问题标题】:How to use MongoDB $ne on nested object property如何在嵌套对象属性上使用 MongoDB $ne
【发布时间】: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;

【问题讨论】:

    标签: node.js mongodb mongoose


    【解决方案1】:

    回答您关于如何使用$ne的问题:

    $ne的用法如下:

    "field":{
      "$ne": yourValue
    }
    

    进入你的查询应该是这样的:

    "user._id": {
      "$ne": req.user.id
    }
    

    例如here

    $ne 运算符将返回字段值与给定值不匹配的所有文档。

    正如您所做的那样,访问嵌套字段必须使用点表示法。

    此外,为确保其正常工作,如果您的架构将 _id 定义为 ObjectId,则可能有必要将 req.user.id 解析为 ObjectId
    但是,如果在您的架构中是一个字符串,那么应该可以工作。

    所以试试(根本没有测试):

    const injected = {
      'user._id': { "$ne": req.user.id }
    };
    

    【讨论】:

    • 嘿,谢谢!但它似乎不起作用;我仍然从登录用户那里得到结果。我也尝试用硬编码字符串替换 req.user.id。
    • 我也试过这样:'user._id': { ne: new mongoose.Types.ObjectId(req.user.id) },没有运气。 (我从 ne 中删除了 $,因为如果您注意到我的代码稍后会添加它。
    • 你能发布你的req对象吗?
    • 整个请求还是只是查询?在我创建运算符后,queryStr 的控制台日志给出(这里的 id 是假的): queryStr: {"access":"public","user._id":{"$ne":"5t845tu495t83r3iuf3rf"}}跨度>
    • 您的查询正在寻找access:"public",但您的模型只有字段nameuser。我使用 name:"Awesome post" 而不是 "access":"public" 并且它有效。如果您的数据或模型已更改,请编辑 OP,我将再次执行。
    猜你喜欢
    • 2016-11-25
    • 2011-10-08
    • 2021-12-30
    • 2022-11-13
    • 1970-01-01
    • 2016-01-13
    • 1970-01-01
    • 2020-03-09
    • 2017-01-16
    相关资源
    最近更新 更多