Не могу думать гораздо лучше, чем подход, чтобы создать дополнительное поле массива с каждый документ в коллекции, который имеет упорядоченный список. Размотайте это поле и используйте свойство includeArrayIndex
оператора $unwind
для создания позиций индекса. Используйте эту информацию для сортировки документов с дополнительным оператором tenary $cond
, который оценивает логическое выражение array element === coreId
и в зависимости от результата возвращает индекс сортировки, если true, в противном случае возвращает константу n > order.length
.
Ниже представлен подход, описанный выше, хотя есть много возможностей для улучшения, но по крайней мере это должно дать вам какое-то направление. Конечно, это будет до вас, чтобы преобразовать трубопровод к языку соответствующего драйвера (который я предполагаю, это PHP):
var order = [20, 10];
db.records.aggregate([
{
"$project": {
"coreId" : 1,
"name" : 1,
"sortOrder": { "$literal": order } // create an additional field
}
},
{
"$unwind": {
// flatten the above array
"path": "$sortOrder",
// create the index position for each array element
"includeArrayIndex": "sortIndex",
}
},
{
"$project": {
"coreId": 1,
"name": 1,
"sortIndex": {
"$cond": [
{ "$eq": [ "$coreId", "$sortOrder" ] },
"$sortIndex", 999999
]
}
}
},
{ "$sort": { "sortIndex": 1 } },
{
"$group": {
"_id": "$coreId",
"name": { "$first": "$name" },
"index": { "$first": "$sortIndex" }
}
},
{ "$sort": { "index": 1 } },
{
"$project": {
"_id": 0,
"coreId" : "$_id",
"name" : 1
}
}
])
Пример Результат
/* 1 */
{
"name" : "a",
"coreId" : 20
}
/* 2 */
{
"name" : "a",
"coreId" : 10
}
/* 3 */
{
"name" : "a",
"coreId" : 30
}