假设我的收藏中有以下文档:
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“值的差异。
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 }
]3)按“差异”排序
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 }
]4)返回结果
发布于 2016-05-01 10:44:36
如果您的.aggregate()服务器版本为3.2或更高版本,则最好的方法是使用MongoDB。管道的第一步是使用$match聚合管道操作符过滤"myArray“长度小于2的所有文档。此操作还减少了在管道下处理的文档数量。下一个阶段是$project阶段,在这里使用$arrayElemAt操作符,它在指定索引处返回元素,在这里,数组中的最后两个元素使用索引-1和索引-2。当然,这里的$let运算符用于将这些值赋值给一个变量,然后在$subtract表达式中使用这些变量来返回差异。最后一个阶段是对文档进行排序的$sort聚合管道阶段。
db.collection.aggregate([
{ "$match": { "myArray.1": { "$exists": true } } },
{ "$project": {
"myArray": "$myArray",
"diff": {
"$let": {
"vars": {
"first": { "$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 }我不知道有什么方法可以做到这一点,但是您总是可以使用Array.sort来完成这个客户端的工作。
db.collection.find({ "myArray.1": { "$exists": true } }).toArray().sort(
function(a, b) {
return a === b ? 0 :( a < b ? -1 : 1 );
}
)这将返回与使用聚合框架的查询相同的结果,但"diff“字段不存在。同样值得一提的是,聚合解决方案比这快得多。
https://stackoverflow.com/questions/36965059
复制相似问题