【问题标题】:nodejs+mongodb access node.js object with document's _id field value in querynodejs+mongodb 在查询中使用文档的 _id 字段值访问 node.js 对象
【发布时间】:2020-09-18 09:56:56
【问题描述】:

我正在学习 Mongodb 与 NodeJS 一起使用。以下是我的代码:

let configMap = {
    '1': 10,
    '2': 12,
    '3': 13
}
let myData = await mongo_groups_collection.find({
    _id: {
        $in: [1,2,3]
    },
    active: true
}).project({
    '_id': 1,
    'name': 1,
    'members': 1,
    'messages': {
        $slice: [-(configMap[_id]), (DEFAULT_PAGE_SIZE_FILL * PAGE_SIZE) + (PAGE_SIZE - ((configMap[_id]) % PAGE_SIZE))] //Need to use _id to get configMap value

    }
}).toArray();

我在 Mongo 切片函数中使用“configMap”nodeJS 变量从数组中检索一定数量的元素。要检索,我需要使用我没有得到的“_id”字段值进行查找并遇到 _id“未定义”错误。

【问题讨论】:

    标签: node.js mongodb mongodb-query aggregation-framework


    【解决方案1】:

    那是因为(configMap[_id]) 在 node.js 代码中编译,而不是作为查询在数据库中编译。因此,在编译此查询时的代码中,它无法找到 _id,因为您没有将它声明为您为 configMap 变量所做的方式。

    您期望 _id 值是来自文档的实际 _id。因此,如果您使用(configMap[$_id]),它就不会那样工作,因为您不能将javascript对象与文档字段结合起来。

    您仍然可以使用如下所示的 aggregate 查询来执行此操作 - 我们实际上将所需的 v 值作为字段添加到文档以供进一步使用:

     /** Make `configMap` an array of objects */
    var configMap = [
      { k: 1, v: 10 },
      { k: 2, v: 12 },
      { k: 3, v: 13 },
    ];
    
    let myData = await mongo_groups_collection.aggregate([
      {
        $match: { _id: { $in: [1, 2, 3] }, active: true }
      },
      /** For each matched doc we'll iterate on input `configMap` array &
       *  find respective `v` value from matched object where `k == _id`  */
      {
        $addFields: {
          valueToBeSliced: {
            $let: {
              vars: { matchedK: { $arrayElemAt: [ { $filter: { input: configMap, cond: { $eq: ["$$this.k", "$_id"] } } }, 0 ] } },
              in: "$$matchedK.v",
            }
          }
        }
      },
      {
        $project: {
          messages: { $slice: ["$messages", { $subtract: [0, "$valueToBeSliced"] }, someInputValue ] },
          name: 1, members: 1
        }
      }
    ]).toArray();
    

    参考: $let

    注意:

    1. 在投影中您无需提及此'_id': 1,因为它默认包含在内。
    2. 由于您的查询使用.find(),您可能使用$slice-projection-operator,它不能用于聚合,我们需要使用$slice-aggregation-operator,两者的作用相同,但语法不同,您需要参考相关文档。
    3. 同样在someInputValue 中,您需要传入(DEFAULT_PAGE_SIZE_FILL * PAGE_SIZE) + (PAGE_SIZE - ((configMap[_id]) % PAGE_SIZE)) 的值 - 所以尝试使用聚合运算符$divide 来获取值。我们正在使用{ $subtract: [0, "$valueToBeSliced"] } 将正数valueToBeSliced 转换为负数,因为我们不能像我们通常在javaScript 中那样做的-valueToBeSliced

    【讨论】:

      猜你喜欢
      • 2017-09-13
      • 2015-11-08
      • 1970-01-01
      • 2012-04-05
      • 2016-07-04
      • 1970-01-01
      • 2015-06-13
      • 1970-01-01
      • 2018-12-01
      相关资源
      最近更新 更多