Javascript 在mongodb中如何根据数组内容的不同进行排序?

Javascript 在mongodb中如何根据数组内容的不同进行排序?,javascript,mongodb,sorting,mongodb-query,aggregation-framework,Javascript,Mongodb,Sorting,Mongodb Query,Aggregation Framework,假设我的收藏中有以下文档: var data = [ { myArray: [ { a:1 }, { a:45 }, { a:46 } ] }, { myArray: [ { a:3 } ] }, { myArray: [ { a:12 }, { a:3 } ] }, { myArray: [ { a:14 }, { a:33 }, { a:66 } ] } ] 我想根据“myArray”中最后两个“a”值的差值

假设我的收藏中有以下文档:

var data = [
         { myArray: [ { a:1 }, { a:45 }, { a:46 } ] },
         { myArray: [ { a:3 } ] },
         { myArray: [ { a:12 }, { a:3 } ] },
         { myArray: [ { a:14 }, { a:33 }, { a:66 } ] }
     ]
我想根据“myArray”中最后两个“a”值的差值对它们进行排序

因此,算法应该是:

1) 拒绝myArray长度小于2的任何文档

var result = [
         { myArray: [ { a:1 }, { a:45 }, { a:46 } ] },
         { myArray: [ { a:12 }, { a:3 } ] },
         { myArray: [ { a:14 }, { a:33 }, { a:66 } ] }
     ]
2) 找出最后两个“a”值的差异

3) 按“差异”排序


4) 返回结果

如果您的MongoDB服务器版本为3.2或更高版本,则最好使用。管道中的第一个阶段是使用聚合管道操作符过滤掉“myArray”长度小于
2
的所有文档。此操作还可以减少后续处理的文档数量。下一个阶段是使用运算符返回指定索引处的元素的阶段,这里使用索引
-1
和索引
-2
返回数组中的最后两个元素。当然,这里的运算符用于将这些值赋给变量,然后在表达式中使用这些变量返回差值。最后一个阶段是聚合管道阶段,您可以在其中对文档进行排序

db.collection.aggregate([
{“$match”:{“myArray.1”:{“$exists”:true}},
{“$project”:{
“myArray”:“$myArray”,
“差异”:{
“$let”:{
“vars”:{
“第一个”:{“$arrayElemAt”:[“$myArray”,-2]},
“last”:{“$arrayElemAt”:[“$myArray”,-1]}
}, 
“in”:{“$subtract”:[“$$last.a”,“$$first.a”]}
} 
} 
}}, 
{“$sort”:{“diff”:-1}
])
产生了这样的结果:

{“myArray”:[{a:14},{a:33},{a:66}],“diff:33}
{“myArray”:[{“a”:1},{“a”:45},{“a”:46}],“diff”:1}
{“myArray”:[{“a”:12},{“a”:3}],“diff”:-9}
我不认为有一种方法可以做到这一点,但您可以使用

db.collection.find({“myArray.1”:{“$exists”:true}}).toArray().sort(
函数(a,b){
返回a===b?0:(a

这将返回与使用聚合框架的查询相同的结果,只是缺少“diff”字段。另外值得一提的是,聚合解决方案比这快得多

假设我只运行不支持$arrayElemAt的v3.0(mlab),有解决方法吗?@mikeysee在这种情况下,您需要在客户端执行此操作。如最后一个代码块所示。
var result = [
         { myArray: [ { a:1 }, { a:45 }, { a:46 } ], diff: 1 },
         { myArray: [ { a:12 }, { a:3 } ], diff: -9 },
         { myArray: [ { a:14 }, { a:33 }, { a:66 } ], diff: 33 }
     ]
var result = [
         { myArray: [ { a:14 }, { a:33 }, { a:66 } ], diff: 33 },
         { myArray: [ { a:1 }, { a:45 }, { a:46 } ], diff: 1 },
         { myArray: [ { a:12 }, { a:3 } ], diff: -9 }             
     ]