Mongo DB聚合管道对嵌套数组对象值进行排序

时间:2019-08-21 04:40:04

标签: mongodb sorting mongodb-query aggregation-framework aggregation

我的mongo文档具有以下结构:

{
    name: 'AKL to DUD Via CHC',
    rates: [
        {
            container_id: 'abc',
            buyRate: 380
        },
        {
            container_id: 'def',
            buyRate: 410
        }
    ]
}
{
    name: 'AKL to DUD',
    rates: [
        {
            container_id: 'abc',
            buyRate: 400
        },
        {
            container_id: 'def',
            buyRate: 420
        }
    ]
}

我想在聚合管道中基于特定buyRate的{​​{1}}进行排序,例如如果我传入了container_id的{​​{1}},我想对container_id的{​​{1}}进行排序,以便(在这种情况下)首先返回第二个文档。 / p>

我可以通过添加一个由abc过滤后的费率的字段,然后对其进行排序来使它起作用,但这似乎过于复杂:

buyRate

是否有更简洁的方法来实现这一目标?

2 个答案:

答案 0 :(得分:3)

您的方法很好。

另一种方式:

  

差异为$addFields将添加一个字段作为对象。

Working example.

db.getCollection('Example').aggregate([
  { $addFields: {
    containerBuyRate: {$arrayElemAt: [ "$rates", { $indexOfArray: [ "$rates.container_id", "abc" ] } ] }}
  },
  { $sort: {'containerBuyRate.buyRate': -1}}
])

输出:

[
  {
    "_id": ObjectId("5a934e000102030405000002"),
    "containerBuyRate": {
      "buyRate": 405,
      "container_id": "abc"
    },
    "name": "AKL to DUD Via CHC",
    "rates": [
      {
        "buyRate": 405,
        "container_id": "abc"
      },
      {
        "buyRate": 500,
        "container_id": "def"
      }
    ]
  },
  {
    "_id": ObjectId("5a934e000102030405000001"),
    "containerBuyRate": {
      "buyRate": 400,
      "container_id": "abc"
    },
    "name": "AKL to DUD",
    "rates": [
      {
        "buyRate": 400,
        "container_id": "abc"
      },
      {
        "buyRate": 420,
        "container_id": "def"
      }
    ]
  },
  {
    "_id": ObjectId("5a934e000102030405000000"),
    "containerBuyRate": {
      "buyRate": 380,
      "container_id": "abc"
    },
    "name": "AKL to DUD Via CHC",
    "rates": [
      {
        "buyRate": 380,
        "container_id": "abc"
      },
      {
        "buyRate": 410,
        "container_id": "def"
      }
    ]
  },
  {
    "_id": ObjectId("5a934e000102030405000003"),
    "containerBuyRate": {
      "buyRate": 300,
      "container_id": "abc"
    },
    "name": "AKL to DUD Via CHC",
    "rates": [
      {
        "buyRate": 300,
        "container_id": "abc"
      },
      {
        "buyRate": 700,
        "container_id": "def"
      }
    ]
  },
  {
    "_id": ObjectId("5a934e000102030405000004"),
    "containerBuyRate": {
      "buyRate": 100,
      "container_id": "abc"
    },
    "name": "AKL to DUD Via CHC",
    "rates": [
      {
        "buyRate": 1000,
        "container_id": "def"
      },
      {
        "buyRate": 100,
        "container_id": "abc"
      }
    ]
  }
]

谢谢@Alex指出我在上一个解决方案中的错误。

答案 1 :(得分:1)

要对containerBuyRate数组进行排序,您需要对其进行展开和排序

db.services.aggregate([
     { $addFields: { "containerBuyRate":
        { $filter: {
            input: "$rates",
            as: "rate",
            cond: { $eq: [ "$$rate.container_id", "abc" ] }
        }}
     }},
     { $unwind: "$containerBuyRate" },
     { $sort: {"containerBuyRate.buyRate": -1}},
     { $group: { 
         _id: "$_id",
         containerBuyRate: {$push: "$containerBuyRate"},
         name: { $first: "$name"},
         rates: {$first: "$rates"} 
     }}
])