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