在查询中具有文档_id字段值的nodejs + mongodb访问node.js对象

时间:2020-05-30 22:44:57

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

我正在学习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 slice函数中使用“ configMap” nodeJS变量从数组中检索一定数量的元素。要进行检索,我需要使用我没有得到的“ _id”字段值进行查找,并遇到_id“未定义”错误。

1 个答案:

答案 0 :(得分: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