如何按自定义顺序对 Mongo 中的数据进行排序 [英] How to sort data in Mongo in a custom order

查看:108
本文介绍了如何按自定义顺序对 Mongo 中的数据进行排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何使用 Mongo 功能对这些数据进行排序:

输入

{ "_id" : 1, "domainName" : "test1.com", "hosting" : "hostgator.com" }{_id":2,域名":test2.com",托管":aws.amazon.com"}{_id":3,域名":test3.com",托管":aws.amazon.com"}{_id":4,域名":test4.com",托管":hostgator.com"}{_id":5,域名":test5.com",托管":aws.amazon.com"}{_id":6,域名":test6.com",托管":cloud.google.com"}{_id":7,域名":test7.com",托管":aws.amazon.com"}{_id":8,域名":test8.com",托管":hostgator.com"}{_id":9,域名":test9.com",托管":cloud.google.com"}{_id":10,域名":test10.com",托管":godaddy.com"}

按托管字段的顺序,获取结果,例如按以下顺序:

1) 首先 - 所有godaddy;

2) 其次 - 所有 AWS;

3) 然后是其他一切.

输出

<代码>{结果" : [{_id":10,"域名": "test10.com",托管":godaddy.com"},{_id":2,"域名": "test2.com",托管":aws.amazon.com"},{_id":3,"域名": "test3.com",托管":aws.amazon.com"},{_id":5,"域名": "test5.com",托管":aws.amazon.com"},{_id":7,"域名": "test7.com",托管":aws.amazon.com"},{_id":1,"域名": "test1.com",托管":hostgator.com"},{_id":4,"域名": "test4.com",托管":hostgator.com"},{_id":6,"域名": "test6.com",托管":cloud.google.com"},{_id":8,"域名": "test8.com",托管":hostgator.com"},{_id":9,"域名": "test9.com",托管":cloud.google.com"},]}

在这个例子中,我想以更相关的方式为用户返回结果.在原始任务中,我想使用其他一些提供附加信息的集合对其进行排序.

但是如果你帮助我完成之前的任务就足够了吗?

UPD:关于问题的第二部分.

另一个任务是如何从一个集合中返回可排序的数据,并依赖于另一个集合.

示例:

第一个集合与之前给出的相同:

 { "_id" : 1, "domainName" : "test1.com", "hosting" : "hostgator.com" }...

第二个集合,提供一些关于托管的额外信息:

{ '_id': 123, 'quality':'best', 'hostings': ["hostgator.com", "aws.amazon.com"]},{ '_id': 321, 'quality':'good', 'hostings': ["cloud.google.com"]},{ '_id': 345, 'quality':'bad', 'hostings': ["godaddy.com"]},

结果,我需要按以下顺序从第一个收集数据返回:

1) 首先所有好的主机2)其次一切都好3) 第三个都不好

输出:

<代码>{结果" : [//最好的:{_id":1,"域名": "test1.com",托管":hostgator.com"},{_id":4,"域名": "test4.com",托管":hostgator.com"},{_id":8,"域名": "test8.com",托管":hostgator.com"},{_id":2,"域名": "test2.com",托管":aws.amazon.com"},{_id":3,"域名": "test3.com",托管":aws.amazon.com"},{_id":5,"域名": "test5.com",托管":aws.amazon.com"},{_id":7,"域名": "test7.com",托管":aws.amazon.com"},//好的:{_id":9,"域名": "test9.com",托管":cloud.google.com"},{_id":6,"域名": "test6.com",托管":cloud.google.com"},//坏的{_id":10,"域名": "test10.com",托管":godaddy.com"}]}

更新 2

我在前面的例子中得到了很好的答案和例子.非常感谢!但我举了另一个例子.

我需要比较 3 个集合的 ID 以按顺序排序 - 第一个:朋友,第二个:'请求',以及:其他用户.

输入

db.friends.find({userId: currentUser});//{"_id" : "PgC7LrtaZtQsShtzT", "userId" : "tHuxnWxFLHvcpRgHb", "friendId" : "jZagPF7bd4aW8agXb",}db.requests.find({userId: currentUser});//看起来像朋友,但带有 'requesterId'

现在我需要聚合用户"集合,定义与前两个集合(朋友、请求)匹配的分数.

使用提供的答案,我管理了结果,但只有一个集合.我怎样才能用 3 个或多个来做这个?

解决方案

您可以将每个 hosting 投影到由整数表示的单独类型,最后对这些整数进行排序.在下面的聚合管道中说明

<预><代码>[{$查找:{来自:'secondCollectionStoringQuality',localField: '托管',ForeignField: '托管',如:'nw'}},{$unwind: '$nw'},{$项目:{域名:1,主持:1、类型: {$cond: [{$eq: ['$nw.quality', 'best']},0,{$cond: [{$eq: ['$nw.quality', 'good']},1、2]}]}}},{$排序:{类型:1}}]

How I can sort this data, using Mongo functionality:

Input

{ "_id" : 1, "domainName" : "test1.com", "hosting" : "hostgator.com" }
{ "_id" : 2, "domainName" : "test2.com", "hosting" : "aws.amazon.com"}
{ "_id" : 3, "domainName" : "test3.com", "hosting" : "aws.amazon.com" }
{ "_id" : 4, "domainName" : "test4.com", "hosting" : "hostgator.com" }
{ "_id" : 5, "domainName" : "test5.com", "hosting" : "aws.amazon.com" }
{ "_id" : 6, "domainName" : "test6.com", "hosting" : "cloud.google.com" }
{ "_id" : 7, "domainName" : "test7.com", "hosting" : "aws.amazon.com" }
{ "_id" : 8, "domainName" : "test8.com", "hosting" : "hostgator.com" }
{ "_id" : 9, "domainName" : "test9.com", "hosting" : "cloud.google.com" }
{ "_id" : 10, "domainName" : "test10.com", "hosting" : "godaddy.com" }

In order by hosting field, to get result, for example in this order:

1) First - all godaddy;

2) Second - all AWS;

3) and next, everything else.

Output

{
    "result" : [
            {

                    "_id" : 10, 
                    "domainName" : "test10.com",
                    "hosting" : "godaddy.com"
            },
            {
                    "_id" : 2, 
                    "domainName" : "test2.com",
                    "hosting" : "aws.amazon.com"
            },
            {
                    "_id" : 3, 
                    "domainName" : "test3.com",
                    "hosting" : "aws.amazon.com"
            },
            {
                    "_id" : 5, 
                    "domainName" : "test5.com",
                    "hosting" : "aws.amazon.com"
            },
            {
                    "_id" : 7, 
                    "domainName" : "test7.com",
                    "hosting" : "aws.amazon.com"
            },
            {
                    "_id" : 1, 
                    "domainName" : "test1.com",
                    "hosting" : "hostgator.com"
            },
            {
                    "_id" : 4, 
                    "domainName" : "test4.com",
                    "hosting" : "hostgator.com"
            },
            {
                    "_id" : 6, 
                    "domainName" : "test6.com",
                    "hosting" : "cloud.google.com"
            },
            {
                    "_id" : 8, 
                    "domainName" : "test8.com",
                    "hosting" : "hostgator.com"
            },
            {
                    "_id" : 9, 
                    "domainName" : "test9.com",
                    "hosting" : "cloud.google.com"
            },
    ]
    }

With this example i want to return results in more relevant way for user. And in origanl task I want to sort this using few another collections, which serve additional information.

But will be good enough if you helps me with previous task?

UPD: About second part of question.

One more task is how to return sortable data from one collection in dependence of another.

Example:

first collection the same which was given before:

 { "_id" : 1, "domainName" : "test1.com", "hosting" : "hostgator.com" }
 ...

second collection, provide some additional info about hosting:

{ '_id': 123, 'quality':'best', 'hostings': ["hostgator.com",  "aws.amazon.com"]},
{ '_id': 321, 'quality':'good', 'hostings': ["cloud.google.com"]},
{ '_id': 345, 'quality':'bad', 'hostings': ["godaddy.com"]},

And in result, I need to return from first collection data in this order:

1) First all good hostings 2) second all good 3) third all bad

Output:

{
"result" : [
        //Best:
        {
                "_id" : 1, 
                "domainName" : "test1.com",
                "hosting" : "hostgator.com"
        },
        {
                "_id" : 4, 
                "domainName" : "test4.com",
                "hosting" : "hostgator.com"
        },
        {
                "_id" : 8, 
                "domainName" : "test8.com",
                "hosting" : "hostgator.com"
        },
        {
                "_id" : 2, 
                "domainName" : "test2.com",
                "hosting" : "aws.amazon.com"
        },
        {
                "_id" : 3, 
                "domainName" : "test3.com",
                "hosting" : "aws.amazon.com"
        },
        {
                "_id" : 5, 
                "domainName" : "test5.com",
                "hosting" : "aws.amazon.com"
        },
        {
                "_id" : 7, 
                "domainName" : "test7.com",
                "hosting" : "aws.amazon.com"
        },

       // Good:
        {
                "_id" : 9, 
                "domainName" : "test9.com",
                "hosting" : "cloud.google.com"
        },
        {
                "_id" : 6, 
                "domainName" : "test6.com",
                "hosting" : "cloud.google.com"
        },

       //Bad
        {
                "_id" : 10, 
                "domainName" : "test10.com",
                "hosting" : "godaddy.com"
        }
]
}

UPDATE 2

I get good answer and example on previous example. Thank you so much! But I stack with another example.

I need to compare IDs of 3 collections to sort in order - first: friend, second: 'requests', and: other users.

Input

db.friends.find({userId: currentUser});
    // {"_id" : "PgC7LrtaZtQsShtzT", "userId" : "tHuxnWxFLHvcpRgHb", "friendId" : "jZagPF7bd4aW8agXb",}
db.requests.find({userId: currentUser});
   // looks like friend but with 'requesterId'

And now I need to aggregate 'users' collection, define the score which matches with previous two collections (friends, requests).

Using provided answer, I managed result but only with one collection. How can I make this with 3 or multiple?

解决方案

You can project each of the hosting into separate type denoted by integers, and finally sort on these integers. Illustrated in the aggregation pipeline below

[
{$lookup: {
    from: 'secondCollectionStoringQuality',
    localField: 'hosting',
    foreignField: 'hostings',
    as: 'nw'
    }},
{$unwind: '$nw'},
{$project: {
        domainName: 1,
        hosting: 1,
        type: {
            $cond: [
                {$eq: ['$nw.quality', 'best']},
                0,
                {$cond: [
                    {$eq: ['$nw.quality', 'good']},
                    1,
                    2
                    ]}
            ]
        }
    }},
    {$sort: {type: 1}}
]

这篇关于如何按自定义顺序对 Mongo 中的数据进行排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆