Mongodb 如何使用聚合对一个mongo文档中的多个数组进行独立排序
经过一些聚合后,我只有一个这样的文档:Mongodb 如何使用聚合对一个mongo文档中的多个数组进行独立排序,mongodb,aggregation-framework,aggregate,Mongodb,Aggregation Framework,Aggregate,经过一些聚合后,我只有一个这样的文档: { 答:[3,5,8,1,…], b:[5,2,6,5,…], c:[2,6,3,1,…] } 获得以下信息的最佳方式是什么: { a:[1,2,3,4,...], b:[1,2,3,4,...], c:[1,2,3,4,...] } 我需要对它进行排序以进行其他聚合,这样我就不能使用查找或更新我得到的最接近的工作解决方案是以下聚合: [ { $facet: { a: [ { $unwind: '$a
{
答:[3,5,8,1,…],
b:[5,2,6,5,…],
c:[2,6,3,1,…]
}
获得以下信息的最佳方式是什么:
{
a:[1,2,3,4,...],
b:[1,2,3,4,...],
c:[1,2,3,4,...]
}
我需要对它进行排序以进行其他聚合,这样我就不能使用
查找
或更新
我得到的最接近的工作解决方案是以下聚合:
[
{
$facet: {
a: [
{ $unwind: '$a' },
{ $sort: { a: 1 } },
{
$group: {
_id: '$_id',
a: { $push: '$a' }
}
}
],
b: [
{ $unwind: '$b' },
{ $sort: { b: 1 } },
{
$group: {
_id: '$_id',
b: { $push: '$b' }
}
}
],
c: [
{ $unwind: '$c' },
{ $sort: { c: 1 } },
{
$group: {
_id: '$_id',
c: { $push: '$c' }
}
}
]
}
},
{
$set: {
a: { $arrayElemAt: ['$a.a', 0] },
b: { $arrayElemAt: ['$b.b', 0] },
c: { $arrayElemAt: ['$c.c', 0] }
}
}
]
简而言之,它的作用是:$facet
并行地对每个a
、b
、c
字段执行相同的操作;每个字段用$unwind
拆分,按升序排序,然后按自身分组
到目前为止,我们已经对字段进行了排序,但每个字段现在都是具有适当名称的对象(例如,{u id:'',a:[…]}
)。因此,要返回到前面的数组,另一个阶段是只从每个对象提取所需的字段。这是通过$set
和$arrayElemAt
(取第一个数组字段)完成的。
因此,最后我们将每个字段按升序排序,同时拥有相同数量的文档
注意:这仅适用于只有一个结果文档的情况。如果有多个结果文档,则需要稍微更改阶段:
阶段保持不变$facet
- 更新的
(第二)阶段更改为:$set
$unwind
+updated$set
阶段(在这种情况下,我们有a
,b
,c
):
这可能不是最漂亮的方法,但我找不到较短的版本。从4.4版开始,您可以直接使用javascript对数组进行使用和排序
db.collection.aggregate([
{
$set: {
"a": {
$function: {
body: "function(a){a.sort((x, y)=>x-y);return a;}",
args: [
"$a"
],
lang: "js"
}
},
"b": {
$function: {
body: "function(b){b.sort((x, y)=>x-y);return b;}",
args: [
"$b"
],
lang: "js"
}
},
"c": {
$function: {
body: "function(c){c.sort((x, y)=>x-y);return c;}",
args: [
"$c"
],
lang: "js"
}
}
}
}
])
.谢谢,我不知道
$facet
操作符,我也在做同样的事情,但不是并行的,所以它真的很有用@Vee是的,这对我来说还是一件相对新鲜的事情,但我已经发现了一些非常有用的例子:)第一次听到这个,但它很有趣,看起来非常有用(尽管我想知道它是否是一个快速的操作符)
db.collection.aggregate([
{
$set: {
"a": {
$function: {
body: "function(a){a.sort((x, y)=>x-y);return a;}",
args: [
"$a"
],
lang: "js"
}
},
"b": {
$function: {
body: "function(b){b.sort((x, y)=>x-y);return b;}",
args: [
"$b"
],
lang: "js"
}
},
"c": {
$function: {
body: "function(c){c.sort((x, y)=>x-y);return c;}",
args: [
"$c"
],
lang: "js"
}
}
}
}
])