mongodb 对未填充的子文档进行排序
mongodb sort unpopulated subdocument
我正在尝试对未绑定的子文档进行排序。这是合集:
[
{
otherFields: {},
visites: ["58d46ffbf1c383862cf5de4a", "58d46ffbf1c383862cf5de49"]
}
]
这是合计:
db.exps.aggregate([
{ "$match": {} },
{ "$project": { "visites": 1 } },
{ "$unwind": "$visites" },
{ "$sort": { "visites.formVersion": 1 } },
{ "$group": { "_id": null, "count": { "$sum": 1 }, "data": { "$push": "$visites" } } }
])
我意识到用子字段排序是没有意义的,因为 visites
字段只是一个 ID 数组。是否可以将它们填充到聚合中,以便对它们进行排序?
nodejs填充后的结果是这些:
{
"count": 50,
"data": [
{
"_id": "58d46ffbf1c383862cf5de4a",
"formVersion": 4,
"start": "2017-06-04T07:30:00.000Z",
"end": "2017-06-04T08:30:00.000Z",
"type": "assessor",
"expedient": "58d46ffaf1c383862cf5de41",
"user": "58d46ff8f1c383862cf5de3a",
"__v": 0,
"isDeleted": false,
"lastModified": "2017-03-24T01:01:47.343Z",
"created": "2017-03-24T01:01:47.330Z"
},
{
"_id": "58d46ffbf1c383862cf5de49",
"formVersion": 3,
"start": "2017-06-03T07:30:00.000Z",
"end": "2017-06-03T08:30:00.000Z",
"type": "assessor",
"expedient": "58d46ffaf1c383862cf5de41",
"user": "58d46ff8f1c383862cf5de3a",
"__v": 0,
"isDeleted": false,
"lastModified": "2017-03-24T01:01:47.341Z",
"created": "2017-03-24T01:01:47.328Z"
},
假设两个集合 coll1
和 coll2
:
> db.coll1.find()
{
"_id": ObjectId("58eecf2a11b7af6f560666d8"),
"otherFields": {
},
"visites": [
"58d46ffbf1c383862cf5de4a",
"58d46ffbf1c383862cf5de49"
]
}
> db.coll2.find()
{
"_id": "58d46ffbf1c383862cf5de4a",
"formVersion": 4,
"start": "2017-06-04T07:30:00.000Z",
"end": "2017-06-04T08:30:00.000Z",
"type": "assessor",
"expedient": "58d46ffaf1c383862cf5de41",
"user": "58d46ff8f1c383862cf5de3a",
"__v": 0,
"isDeleted": false,
"lastModified": "2017-03-24T01:01:47.343Z",
"created": "2017-03-24T01:01:47.330Z"
}
{
"_id": "58d46ffbf1c383862cf5de49",
"formVersion": 3,
"start": "2017-06-03T07:30:00.000Z",
"end": "2017-06-03T08:30:00.000Z",
"type": "assessor",
"expedient": "58d46ffaf1c383862cf5de41",
"user": "58d46ff8f1c383862cf5de3a",
"__v": 0,
"isDeleted": false,
"lastModified": "2017-03-24T01:01:47.341Z",
"created": "2017-03-24T01:01:47.328Z"
}
如果您希望按例如formVersion
字段,一种可能的聚合管道解决方案可能是:
db.coll1.aggregate([
// left outer join from coll2 to coll1
{$lookup:{
from:"coll2",
localField:"visites",
foreignField:"_id",
as:"data"
}},
// unwind the resulting array
{$unwind:"$data"},
// sort the unwinded documents using the formVersion field
{$sort:{"_id":1 ,"data.formVersion": 1}},
// collect the results into an array
{$group:{"_id":null, data:{$push:"$data"}}}
])
流水线的结果是:
{
"_id": null,
"data": [
{
"_id": "58d46ffbf1c383862cf5de49",
"formVersion": 3,
"start": "2017-06-03T07:30:00.000Z",
"end": "2017-06-03T08:30:00.000Z",
"type": "assessor",
"expedient": "58d46ffaf1c383862cf5de41",
"user": "58d46ff8f1c383862cf5de3a",
"__v": 0,
"isDeleted": false,
"lastModified": "2017-03-24T01:01:47.341Z",
"created": "2017-03-24T01:01:47.328Z"
},
{
"_id": "58d46ffbf1c383862cf5de4a",
"formVersion": 4,
"start": "2017-06-04T07:30:00.000Z",
"end": "2017-06-04T08:30:00.000Z",
"type": "assessor",
"expedient": "58d46ffaf1c383862cf5de41",
"user": "58d46ff8f1c383862cf5de3a",
"__v": 0,
"isDeleted": false,
"lastModified": "2017-03-24T01:01:47.343Z",
"created": "2017-03-24T01:01:47.330Z"
}
]
}
请注意,从 MongoDB 3.4 开始,$lookup
阶段存在某些限制;比如两个集合必须在同一个数据库中,并且from
参数不能是分片集合。详情请见https://docs.mongodb.com/manual/reference/operator/aggregation/lookup/
另请注意,最后的 $group
阶段将生成单个文档,该文档将受到 MongoDB 的 16 MB 文档大小限制的约束。如果您愿意,可以删除 $group
阶段并迭代 $sort
阶段返回的游标。
我正在尝试对未绑定的子文档进行排序。这是合集:
[
{
otherFields: {},
visites: ["58d46ffbf1c383862cf5de4a", "58d46ffbf1c383862cf5de49"]
}
]
这是合计:
db.exps.aggregate([
{ "$match": {} },
{ "$project": { "visites": 1 } },
{ "$unwind": "$visites" },
{ "$sort": { "visites.formVersion": 1 } },
{ "$group": { "_id": null, "count": { "$sum": 1 }, "data": { "$push": "$visites" } } }
])
我意识到用子字段排序是没有意义的,因为 visites
字段只是一个 ID 数组。是否可以将它们填充到聚合中,以便对它们进行排序?
nodejs填充后的结果是这些:
{
"count": 50,
"data": [
{
"_id": "58d46ffbf1c383862cf5de4a",
"formVersion": 4,
"start": "2017-06-04T07:30:00.000Z",
"end": "2017-06-04T08:30:00.000Z",
"type": "assessor",
"expedient": "58d46ffaf1c383862cf5de41",
"user": "58d46ff8f1c383862cf5de3a",
"__v": 0,
"isDeleted": false,
"lastModified": "2017-03-24T01:01:47.343Z",
"created": "2017-03-24T01:01:47.330Z"
},
{
"_id": "58d46ffbf1c383862cf5de49",
"formVersion": 3,
"start": "2017-06-03T07:30:00.000Z",
"end": "2017-06-03T08:30:00.000Z",
"type": "assessor",
"expedient": "58d46ffaf1c383862cf5de41",
"user": "58d46ff8f1c383862cf5de3a",
"__v": 0,
"isDeleted": false,
"lastModified": "2017-03-24T01:01:47.341Z",
"created": "2017-03-24T01:01:47.328Z"
},
假设两个集合 coll1
和 coll2
:
> db.coll1.find()
{
"_id": ObjectId("58eecf2a11b7af6f560666d8"),
"otherFields": {
},
"visites": [
"58d46ffbf1c383862cf5de4a",
"58d46ffbf1c383862cf5de49"
]
}
> db.coll2.find()
{
"_id": "58d46ffbf1c383862cf5de4a",
"formVersion": 4,
"start": "2017-06-04T07:30:00.000Z",
"end": "2017-06-04T08:30:00.000Z",
"type": "assessor",
"expedient": "58d46ffaf1c383862cf5de41",
"user": "58d46ff8f1c383862cf5de3a",
"__v": 0,
"isDeleted": false,
"lastModified": "2017-03-24T01:01:47.343Z",
"created": "2017-03-24T01:01:47.330Z"
}
{
"_id": "58d46ffbf1c383862cf5de49",
"formVersion": 3,
"start": "2017-06-03T07:30:00.000Z",
"end": "2017-06-03T08:30:00.000Z",
"type": "assessor",
"expedient": "58d46ffaf1c383862cf5de41",
"user": "58d46ff8f1c383862cf5de3a",
"__v": 0,
"isDeleted": false,
"lastModified": "2017-03-24T01:01:47.341Z",
"created": "2017-03-24T01:01:47.328Z"
}
如果您希望按例如formVersion
字段,一种可能的聚合管道解决方案可能是:
db.coll1.aggregate([
// left outer join from coll2 to coll1
{$lookup:{
from:"coll2",
localField:"visites",
foreignField:"_id",
as:"data"
}},
// unwind the resulting array
{$unwind:"$data"},
// sort the unwinded documents using the formVersion field
{$sort:{"_id":1 ,"data.formVersion": 1}},
// collect the results into an array
{$group:{"_id":null, data:{$push:"$data"}}}
])
流水线的结果是:
{
"_id": null,
"data": [
{
"_id": "58d46ffbf1c383862cf5de49",
"formVersion": 3,
"start": "2017-06-03T07:30:00.000Z",
"end": "2017-06-03T08:30:00.000Z",
"type": "assessor",
"expedient": "58d46ffaf1c383862cf5de41",
"user": "58d46ff8f1c383862cf5de3a",
"__v": 0,
"isDeleted": false,
"lastModified": "2017-03-24T01:01:47.341Z",
"created": "2017-03-24T01:01:47.328Z"
},
{
"_id": "58d46ffbf1c383862cf5de4a",
"formVersion": 4,
"start": "2017-06-04T07:30:00.000Z",
"end": "2017-06-04T08:30:00.000Z",
"type": "assessor",
"expedient": "58d46ffaf1c383862cf5de41",
"user": "58d46ff8f1c383862cf5de3a",
"__v": 0,
"isDeleted": false,
"lastModified": "2017-03-24T01:01:47.343Z",
"created": "2017-03-24T01:01:47.330Z"
}
]
}
请注意,从 MongoDB 3.4 开始,$lookup
阶段存在某些限制;比如两个集合必须在同一个数据库中,并且from
参数不能是分片集合。详情请见https://docs.mongodb.com/manual/reference/operator/aggregation/lookup/
另请注意,最后的 $group
阶段将生成单个文档,该文档将受到 MongoDB 的 16 MB 文档大小限制的约束。如果您愿意,可以删除 $group
阶段并迭代 $sort
阶段返回的游标。