Mongo 数据库聚合管道对嵌套数组对象值进行排序
Mongo DB aggregation pipeline sort on nested array object values
我有 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
}
]
}
我想根据特定 container_id
的 buyRate
在我的聚合管道中进行排序,例如如果我传入 abc
的 container_id
我想对 abc
的 buyRate
进行排序,以便(在这种情况下)首先返回第二个文档。
我可以通过添加一个由 container_id
筛选比率的字段来使其工作,然后对其进行排序,但它似乎过于复杂:
db.services.aggregate([
{ $addFields: { "containerBuyRate":
{ $filter: {
input: "$rates",
as: "rate",
cond: { $eq: [ "$$rate.container_id", "abc") ] }
}}
}},
{ $sort: {'containerBuyRate.buyRate': -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"}
}}
])
你的方法很好。
另一种方式:
Difference is $addFields
will add one more field as an object.
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 指出我在最后一个解决方案中的错误。
我有 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
}
]
}
我想根据特定 container_id
的 buyRate
在我的聚合管道中进行排序,例如如果我传入 abc
的 container_id
我想对 abc
的 buyRate
进行排序,以便(在这种情况下)首先返回第二个文档。
我可以通过添加一个由 container_id
筛选比率的字段来使其工作,然后对其进行排序,但它似乎过于复杂:
db.services.aggregate([
{ $addFields: { "containerBuyRate":
{ $filter: {
input: "$rates",
as: "rate",
cond: { $eq: [ "$$rate.container_id", "abc") ] }
}}
}},
{ $sort: {'containerBuyRate.buyRate': -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"}
}}
])
你的方法很好。
另一种方式:
Difference is
$addFields
will add one more field as an object.
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 指出我在最后一个解决方案中的错误。