【问题标题】:Mongo complex sorting?Mongo复杂排序?
【发布时间】:2010-07-09 13:19:24
【问题描述】:

我知道如何在 MongoDB 中按多个字段对查询进行排序,例如 db.coll.find().sort({a:1,b:-1})

我可以使用用户定义的函数进行排序吗?例如,假设 a 和 b 是整数,通过 a 和 b 的差 (a-b)?

谢谢!

【问题讨论】:

  • 我遇到了同样的问题。您是否能够找到一种在服务器端完成此任务的方法?我真的不想在客户端上这样做,或者添加额外的字段。

标签: mongodb


【解决方案1】:

更新:此答案似乎已过时;似乎可以或多或少地通过使用$project function of the aggregation pipeline 在排序之前转换输入文档来实现自定义排序。另请参阅@Ari 的回答。


我不认为这是直接可能的; sort documentation 当然没有提到任何提供自定义比较功能的方法。

您可能最好在客户端进行排序,但如果您真的决定在服务器上进行排序,您可以使用db.eval() 安排在服务器上运行排序(如果您客户支持)。

服务器端排序:

db.eval(function() { 
  return db.scratch.find().toArray().sort(function(doc1, doc2) { 
    return doc1.a - doc2.a 
  }) 
});

相对于等效的客户端排序:

db.scratch.find().toArray().sort(function(doc1, doc2) { 
  return doc1.a - doc2.b 
});

请注意,也可以通过aggregation pipeline$orderby operator(即除了.sort())进行排序,但是这两种方式都不允许您提供自定义排序功能。

【讨论】:

  • 是的。在进一步挖掘之后,我发现已经提交了一个 RFE,以允许方便的功能来做到这一点。我绝对不喜欢 toArray() 在我的大约 1000 万份文档中的外观,但这显然是现状。
  • 嗨@gilesc。您能告诉我您是如何详细使用“RFE 归档”的吗?我也有同样的情况。
  • @Wasabi 我想他指的是这个:jira.mongodb.org/browse/SERVER-153 这是不可能的,但是他们正在考虑实施它。但它已经开放多年,所以不确定它是否会发生。
  • 您的排序功能可能有误。应该是return (doc1.a - doc1.b) - (doc2.a - doc2.b)
  • 如@Ari 的回答所示,您可以使用 $project 来实现您的功能并将其分配给一个字段,然后对其进行排序。
【解决方案2】:

遇到了这个问题,这就是我想出的:

db.collection.aggregate([
  { 
    $project: {
      difference: { $subtract: ["$a", "$b"] }
      // Add other keys in here as necessary
    }
  },  
  { 
    $sort: { difference: -1 } 
  }
])

【讨论】:

    【解决方案3】:

    为什么不用这个操作创建字段并对其进行排序?

    【讨论】:

    • 我仍然需要单独访问 a 和 b。所以我必须创建第三个字段。这适用于我的申请,但作为一般原则,这将是非常糟糕的政策。假设我有几个整数字段,那么派生属性 (a-b)、(a-c)、(a-d) 的组合就会爆炸式增长......即使只有一个这样的字段,它确实非常浪费空间,尤其是对于一个大型集合。我赞成,如果没有其他人回答接受,但必须有更好的方法。在 SQL 中,这就像 SELECT * FROM coll ORDER BY (a-b) 一样简单。
    • 请注意,虽然您可以在 SQL 中执行此操作,但效率不高。数据库必须获取所有 a 和 b 值,计算 a-b,对结果进行排序并返回相关记录。对于 Mongo,这意味着如果您在 a 和 b 上没有索引,则将所有文档加载到内存中。如果你创建一个新字段,你可以在这个字段上创建一个索引,这将使这个查询非常快。
    • 好主意。只要记录位置的值被本地化为记录本身的数据,这就完美地摊销了计算插入/更新排序的成本。
    猜你喜欢
    • 2023-03-22
    • 2014-06-30
    • 2015-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-17
    • 2012-11-29
    • 2017-05-27
    相关资源
    最近更新 更多