我正在学习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“未定义”错误。
答案 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
注意:
'_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
。