Reputation: 2731
I am learning Mongodb to use with NodeJS. The below is my code:
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();
I am using "configMap" nodeJS variable in Mongo slice function to retrieve certain number of elements from the array. To retrieve I need to lookup using "_id" field value which I am not getting and encounter _id "undefined" error.
Upvotes: 2
Views: 277
Reputation: 17915
That's because (configMap[_id])
gets compiled in node.js code but not on database as a query. So in code when this query gets compiled it's not able to find _id
since you've not declared it as the way you did it for configMap
variable.
You're expecting _id
value to be actual _id
from document. So, in case if you use (configMap[$_id])
it doesn't work that way cause you can't club a javascript object with documents field.
You can still do this using aggregate
query like below - where we actually add needed v
value as a field to document for further usage :
/** 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();
Ref : $let
Note :
'_id': 1
as it's included by default..find()
you might be using $slice-projection-operator which can't be used in aggregation, instead we need to use $slice-aggregation-operator, both does same thing but have syntax variation, you need to refer to docs for that.someInputValue
you need to pass in value of (DEFAULT_PAGE_SIZE_FILL * PAGE_SIZE) + (PAGE_SIZE - ((configMap[_id]) % PAGE_SIZE))
- So try to use aggregation operators $divide
to get the value. We're doing { $subtract: [0, "$valueToBeSliced"] }
to convert positive valueToBeSliced
to negative as we can't just do like -valueToBeSliced
which we usually do in javaScript.Upvotes: 1