Ну вы всегда можете запустить mapReduce для этого и соответствует индексу массива через .indexOf()
:
db.collection.mapReduce(
function() {
emit(this._id,{ "position": this.otherIds.indexOf(108) });
},
function() {},
{
"out": { "inline": 1 },
"query": { "otherIds": 108 }
}
)
Или для возможного «несколько» матчей, а затем использовать .map()
с дополнительным «индексом» параметр:
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 }
}
)
Но, конечно, индексы массива начинаются с 0
, поэтому, если вы ожидаете, что результат будет 3
, тогда вы n всегда добавляйте 1
в соответствующее положение индекса.
Разумеется, вы просто просто возвращаете массив в ответе на запрос и просто соглашаетесь с позицией (-ами) согласованного элемента в клиентском коде и, вероятно, лучше всего обрабатывать этот путь, если у вас нет особо больших массивов ,
Оператор $arrayElemAt
в настоящее время находится в пределах ветки развития MongoDB, но, к сожалению, он работает наоборот, и вместо того, чтобы возвращать позицию совпадающего элемента, он возвращает элемент в заданной позиции. И поскольку нет никакого способа определить текущую позицию массива или циклически все возможные позиции, он не может быть обратным преобразованием в обеспечение положительного соответствия в заданной позиции.
Также можно утверждать, что другие операторы, такие как $map
, и предстоящий $filter
(также в ветви dev) должны иметь аналогичную возможность, как системную переменную, доступную в этих командах, таких как их JavaScript и другие эквиваленты языков. Тогда что-то вроде $$IDX
(простирания от других системных переменных, как $$ROOT
) доступна, то вы могли бы сделать это под .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] }
}
}
}}
])
Но это еще не произошло, хотя это было бы приятно видеть, и, казалось бы, не трудно спросить поскольку у обоих есть внутренние работы, которые сохраняют текущую позицию индекса в любом случае, поэтому нужно просто разоблачить это для использования в качестве доступной переменной.
Большое спасибо Blakes Seven, я не думаю, что выполнение сокращения карты - лучший подход для моего случая, я попытался бы сохранить данные в другом расположении. – hiamex
@hiamex Вероятно, было бы лучше, если бы вы задали вопрос, который вместо этого объяснил, почему вам нужно это поведение совпадающего индекса. Как указано, в целом, вероятно, лучше всего просто выработать позицию в клиентском коде, если только ваши массивы не являются особенно большими, и у вас есть что-то, что можно получить от других действий. –