Сортировка на основе зависимости двух полей в MongoDB - PullRequest
0 голосов
/ 27 ноября 2018

Я получаю данные из базы данных MongoDB.В объекте данных есть три поля _id, order, parent.они выглядят как

{
  "_id" : 1,
  "parent" : 0,
  "order" : 1,
}
{
  "_id" : 2, 
  "parent" : 0,
  "order" : 2,
}
{
  "_id" : 3,
  "parent" : 5,
  "order" : 1,
}
{
  "_id" : 4,
  "parent" : 5,
  "order" : 2,
}
{
  "_id" : 5,
  "parent" : 0,
  "order" : 3,
}
{
  "_id" : 6,
  "parent" : 2,
  "order" : 1,
}
{
  "_id" : 7,
  "parent" : 2,
  "order" : 2,
}

Используя запрос сортировки в оболочке MongoDB, он также даст тот же результат

 db.menu.find().sort({_id:1,parent:1,order:1}).pretty()

Ожидаемый результат: -

{
  "_id" : 1,
  "parent" : 0,
  "order" : 1,
}
{
  "_id" : 2, 
  "parent" : 0,
  "order" : 2,
}
{
  "_id" : 6,
  "parent" : 2,
  "order" : 1,
}
{
  "_id" : 7,
  "parent" : 2,
  "order" : 2,
}
{
  "_id" : 5,
  "parent" : 0,
  "order" : 3,
}
{
  "_id" : 3,
  "parent" : 5,
  "order" : 1,
}
{
  "_id" : 4,
  "parent" : 5,
  "order" : 2,
}

С помощью какого запроса я должен получить ожидаемый результат?

1 Ответ

0 голосов
/ 27 ноября 2018

Очень сложно отсортировать по зависимости в обычном сценарии.Следовательно, мы сначала накопим приоритет, а затем отсортируем его с помощью агрегации.

db.getCollection('test').aggregate([
  {$project: {
    "id":"$id",
    "parent":1,
    "order":1,
    "accumulator":{$cond:[{$gt:["$parent","$order"]}, "$parent", "$order"]}
  }},
  {$sort: {"accumulator": 1}},
  {$project:{
    "id":"$id",
    "parent":1,
    "order":1
  }}
])

Проверка здесь рабочий пример.

let output = [{"_id":1,"order":1,"parent":0},{"_id":2,"order":2,"parent":0},{"_id":6,"order":1,"parent":2},{"_id":7,"order":2,"parent":2},{"_id":5,"order":3,"parent":0},{"_id":3,"order":1,"parent":5},{"_id":4,"order":2,"parent":5}];
let eOutput = [{"_id":1,"parent":0,"order":1},{"_id":2,"parent":0,"order":2},{"_id":6,"parent":2,"order":1},{"_id":7,"parent":2,"order":2},{"_id":5,"parent":0,"order":3},{"_id":3,"parent":5,"order":1},{"_id":4,"parent":5,"order":2}]

let matchedOutput = true;
for(let i=0; i< eOutput.length; i++){
  if(output[i]._id !== eOutput[i]._id ||
  output[i].parent !== eOutput[i].parent ||
  output[i].order !== eOutput[i].order){
    matchedOutput = false;
    break;
  }
}
console.log("Matched with expected output: ", matchedOutput);
...