用于组的 mongo 排序子文档
Posted
技术标签:
【中文标题】用于组的 mongo 排序子文档【英文标题】:mongo sort subdocument for group 【发布时间】:2018-01-07 10:46:13 【问题描述】:我有一个会员收藏:
"_id": ObjectId("597cace8e68903af813c4fe8"),
"lastName": "Smith",
"firstName": "Lloyd",
"captain": ObjectId("597cace8e68903af813c4fe8")
"_id": ObjectId("597cace8e68903af813c4fec"),
"lastName": "Jones",
"firstName": "Chris",
"captain": ObjectId("597cace8e68903af813c4fe8")
captain 架构属性引用同一集合中的另一个文档。
我还有一个 orders 集合:
"_id" : ObjectId("597cf7e165b6c3f5094080c9"),
"orderTotal" : 99.86,
"orderDate" : ISODate("2017-07-29T21:02:25.045Z"),
"orderProducts" : [
"title" : "Beads",
"totalItemPrice" : 39.96
,
"title" : "Doubloons",
"totalItemPrice" : 59.9
],
"memberId" : ObjectId("597cace8e68903af813c4fec")
memberId 是引用 members 集合的外键。
我正在准备一份报告,该报告如下所示,按船长分组,按升序(姓氏、名字)对船长的姓名进行排序。在队长组中,我希望成员以相同的方式排序:
MEMBER ORDERS
Captain: Lloyd Smith
Members:
1. Chris Jones
* Beads: $39.96
* Doubloons: $59.90
* Total: $99.86
2. Lloyd Smith
* No Orders
etc..
Captain: George Taylor
Members:
1. John Brown
* Beads: $1.96
* Doubloons: $9.00
* Total: $10.96
2. Chip Castle
* Beads: $1.00
* Doubloons: $9.00
* Total: $10.00
etc...
我有一个查询主要做我想要的,但它没有对成员名称进行排序:
Member.aggregate(
$lookup :
from : "orders",
localField : "_id",
foreignField : "memberId",
as : "tmpOrders"
,
$lookup :
from : "members",
localField : "captain",
foreignField : "_id",
as : "tmpCaptains"
,
$group:
_id:
captain: "$captain",
captainFirstName: "$tmpCaptains.firstName",
captainLastName: "$tmpCaptains.lastName"
,
members:
$push: "$$ROOT"
,
$project:
"_id.captainFirstName": 1,
"_id.captainLastName": 1,
"members.firstName": 1,
"members.lastName": 1,
"members.tmpOrders.orderDate": 1,
"members.tmpOrders.orderTotal": 1,
"members.tmpOrders.orderProducts.title": 1,
"members.tmpOrders.orderProducts.totalItemPrice": 1
,
,
$sort:
"_id.captainLastName": 1,
"_id.captainFirstName": 1
)
除了我的排序问题,我愿意接受任何关于提高管道可读性和性能的建议。
【问题讨论】:
【参考方案1】:我终于明白了!我需要$unwind 成员以$sort 他们,再加上一些其他步骤将数据放回所需的结构。
Member.aggregate([
$lookup :
from : "orders",
localField : "_id",
foreignField : "kreweOfTucksId",
as : "tmpOrders"
,
$lookup :
from : "members",
localField : "captain",
foreignField : "_id",
as : "tmpCaptain"
,
$group:
_id: "$captain",
captain:
$addToSet:
firstName: "$tmpCaptain.firstName",
lastName: "$tmpCaptain.lastName"
,
members:
$addToSet:
_id: "$_id",
firstName: "$firstName",
lastName: "$lastName",
captain: "$captain",
orders: "$tmpOrders",
,
$unwind: "$members"
,
$sort:
"members.lastName": 1,
"members.firstName": 1
,
$group:
_id: "$captain",
members:
$push: "$members"
,
$sort:
"_id.lastName": 1,
"_id.firstName": 1
,
$project:
_id: 1,
"members.firstName": 1,
"members.lastName": 1,
"members.orders.orderTotal": 1,
"members.orders.orderDate": 1,
"members.orders.orderProducts.title": 1,
"members.orders.orderProducts.totalItemPrice": 1
])
鉴于生成此报告所需的步骤,我敢打赌有多种方法可以改进查询。如果有任何专家有改进建议,我将不胜感激。谢谢!
【讨论】:
以上是关于用于组的 mongo 排序子文档的主要内容,如果未能解决你的问题,请参考以下文章
Mongo - Java - 将所有文档排序字符串日期作为日期
为啥 Mongoose ORM 选择不使用常规的 mongo 语法进行查找、排序等?