Well you can always run a mapReduce for this and match the array index via .indexOf()
:
db.collection.mapReduce(
function() {
emit(this._id,{ "position": this.otherIds.indexOf(108) });
},
function() {},
{
"out": { "inline": 1 },
"query": { "otherIds": 108 }
}
)
Or for possible "multiple" matches then use .map()
with the optional "index" parameter:
db.collection.mapReduce(
function() {
emit(this._id,{
"positions": this.otherIds.map(function(el,idx) {
return (el == 108) ? idx : -1;
}).filter(function(el) {
return el != -1;
})
});
},
function() {},
{
"out": { "inline": 1 },
"query": { "otherIds": 108 }
}
)
But of course array indexes start at 0
so if you expect the result to be 3
then you can always add 1
to the index position matched.
It is arguable of course that you simply just return the array in the query response and just match the position(s) of the matched element in client code, and it probably is best handled that way unless you have particularly large arrays.
There is an $arrayElemAt
operator currently placed within the development branch of MongoDB, but this unfortunately works the other way around, and rather than returning the position of the matched element it returns the element at a given position. And since there is no present way to determine a current array position or cycle all possible positions it cannot be reverse engineered into providing a positive match at a given position.
It is also arguable that other operators like $map
and the upcoming $filter
( also in dev branch ) should have a similar option as a system variable accessible within those commands like their JavaScript and other language equivalents. Then something like $$IDX
( trending from other system variables like $$ROOT
) available then you could do this under .aggregate()
:
db.collection.aggregate([
{ "$match": { "otherIds": 108 } },
{ "$project": {
"position": {
"$filter": {
"input": {
"$map": {
"input": "$otherIds",
"as": "el",
"in": {
"$cond": [
{ "$eq": [ "$$el", 108 ] },
"$$IDX",
-1
]
}
}
},
"as": "el",
"cond": { "$ne": ["$$el", -1] }
}
}
}}
])
But that is yet to happen, though it would be nice to see, and seemingly not a hard ask as both have internal workings that keep the current index position anyway, so it should just be a matter of exposing that for use as an accessible variable.