首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何根据mongodb中数组内容的差异进行排序?

如何根据mongodb中数组内容的差异进行排序?
EN

Stack Overflow用户
提问于 2016-05-01 09:22:26
回答 1查看 598关注 0票数 2

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

代码语言:javascript
复制
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的文档

代码语言:javascript
复制
var result = [
         { myArray: [ { a:1 }, { a:45 }, { a:46 } ] },
         { myArray: [ { a:12 }, { a:3 } ] },
         { myArray: [ { a:14 }, { a:33 }, { a:66 } ] }
     ]

2)找出最后两个"a“值的差异。

代码语言:javascript
复制
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)按“差异”排序

代码语言:javascript
复制
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)返回结果

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-05-01 10:44:36

如果您的.aggregate()服务器版本为3.2或更高版本,则最好的方法是使用MongoDB。管道的第一步是使用$match聚合管道操作符过滤"myArray“长度小于2的所有文档。此操作还减少了在管道下处理的文档数量。下一个阶段是$project阶段,在这里使用$arrayElemAt操作符,它在指定索引处返回元素,在这里,数组中的最后两个元素使用索引-1和索引-2。当然,这里的$let运算符用于将这些值赋值给一个变量,然后在$subtract表达式中使用这些变量来返回差异。最后一个阶段是对文档进行排序的$sort聚合管道阶段。

代码语言:javascript
复制
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 } }
])

产生了这样的东西:

代码语言:javascript
复制
{ "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来完成这个客户端的工作。

代码语言:javascript
复制
db.collection.find({ "myArray.1": { "$exists": true } }).toArray().sort(
    function(a, b) { 
        return a === b ? 0 :( a < b ? -1 : 1 ); 
    }
)

这将返回与使用聚合框架的查询相同的结果,但"diff“字段不存在。同样值得一提的是,聚合解决方案比这快得多。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36965059

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档