在Mongoid中按多个字段和条件排序集合

itx*_*itx 13 ruby-on-rails mongodb mongoid

我有一个文件,它是在4个领域name,online,likescore.我想通过多个字段和条件来订购带有分页的百万份文件.

示例一些文档:

我的用户文件:

{ "_id": 1, "name": "A", "online": 1, "like": 10, "score": 1 },
{ "_id": 2, "name": "B", "online": 0, "like": 9, "score": 0 },
{ "_id": 3, "name": "C", "online": 0, "like": 8, "score": 1 },
{ "_id": 4, "name": "D", "online": 1, "like": 8, "score": 0 },
{ "_id": 5, "name": "E", "online": 1, "like": 7, "score": 1 },
{ "_id": 6, "name": "F", "online": 0, "like": 10, "score": 0 },
Run Code Online (Sandbox Code Playgroud)

我将通过以下示例解释我的观点(使用数组的示例).

在ruby语言中的例子,我有一个数组结构如下:

[["A", 1, 10, 1],
["B", 0, 9, 1],
["C", 0, 8, 1],
["D", 1, 8, 0],
["E", 1, 7, 1],
["F", 0, 10, 0]]
Run Code Online (Sandbox Code Playgroud)

如果online1应该的降序排序再次like,但是当online0应该的降序再次score.

示例排序:

list.sort{|a, b| a[1] == 1 ? ([-a[1], -a[2]] <=> [-b[1], -b[2]]) : ([-a[1], -a[3]] <=> [-b[1], -b[3]]) }
Run Code Online (Sandbox Code Playgroud)

结果如下:

[["A", 1, 10, 1],
["D", 1, 8, 0],
["E", 1, 7, 1],
["B", 0, 9, 1],
["C", 0, 8, 1],
["F", 0, 10, 0]]
Run Code Online (Sandbox Code Playgroud)

那是一个数组排序,但我的问题是我收集了mongodb和百万文档,我不能使用数组排序,因为它会对数据库负载很重,应该获取所有文件并转换为数组(包括排序)而不是对他们进行分页,我认为这是一个坏主意.

我尝试使用order()/ order_by()mongoid的可选方法,如:

User.
order_by([:online, :desc], [:like, :desc], [:score, :desc]).
hint(online: -1, like: -1, score: -1).
page(1).per(10)
Run Code Online (Sandbox Code Playgroud)

但该查询是通过仅顺序onlinescore,是否有在像阵列排序mongoid排序方法?或者mongodb中有类似冒泡的东西?

同样的问题:Ruby on Rails:连接Mongoid标准和分页的结果,merge方法对我没有帮助,因为它可以取代第一个标准.

itx*_*itx 2

使用聚合$cond

User.collection.aggregate([
      { 
        "$project" => {
            "id" => 1, 
            "name" => 1, 
            "online" => 1, 
            "like" => 1, 
            "score" => 1,
            "sort" => {
                "$cond" => {
                   "if" => { 
                      "$eq" => ["$online", 1] 
                   },
                   "then" => "$like",
                   "else" => "$score"
                }
            }
       }
     },
     { 
        "$sort" => {
            "online" => -1,  
            "sort" => -1,
            "id" => 1
        }
     },
     {
        "$skip" => 0
     { 
        "$limit" => 12 
     }
])
Run Code Online (Sandbox Code Playgroud)

参考 :

  1. https://docs.mongodb.com/manual/reference/operator/aggregation/cond/
  2. https://www.oodlestechnologies.com/blogs/How-to-use-Conditional-Statements-for-sorting-data-in-MongoDB