【问题标题】:Is it possible to key a single sort on multiple fields in MongoDB?是否可以在 MongoDB 中的多个字段上键入单个排序?
【发布时间】:2016-11-05 02:22:44
【问题描述】:

我有一个简单的音乐数据库,其中包含有关 CD 的信息(艺术家、专辑名称、发行年份等)。基本上,我想按艺术家对查询进行排序,然后是发行年份(这很容易做到),但在 CD 没有艺术家的情况下,我希望对专辑标题进行排序。

例如,对于以下 CD:

> db.music.find()
{ "_id" : ObjectId("581d3e073a4d1f0d73a8650b"), "Type" : "CD", "Artist" : "Korn", "Title" : "Korn", "ReleaseYear" : 1994 }
{ "_id" : ObjectId("581d3e283a4d1f0d73a8650c"), "Type" : "CD", "Artist" : "Korn", "Title" : "Life is Peachy", "ReleaseYear" : 1996 }
{ "_id" : ObjectId("581d3efd3a4d1f0d73a8650d"), "Type" : "CD", "Title" : "Big Daddy", "ReleaseYear" : 1999 }
{ "_id" : ObjectId("581d3f3c3a4d1f0d73a8650e"), "Type" : "CD", "Title" : "Aerosmith", "ReleaseYear" : 1973, "Artist" : "Aerosmith" }

我希望它分类为:

Aerosmith - Aerosmith (1973)
Big Daddy (1999)
Korn - Korn (1994)
Korn - Life is Peachy (1996)

这是我尝试过的:

> db.music.find().sort({[Artist:1,Title:1],ReleaseYear:1})
2016-11-04T22:10:39.317-0400 E QUERY    [thread1] SyntaxError: missing ] in computed property name @(shell):1:29
> db.music.find().sort({[Artist,Title]:1,ReleaseYear:1})
2016-11-04T22:10:50.564-0400 E QUERY    [thread1] SyntaxError: missing ] in computed property name @(shell):1:29
> db.music.find().sort({{Artist:1,Title:1},ReleaseYear:1})
2016-11-04T22:11:12.040-0400 E QUERY    [thread1] SyntaxError: invalid property id @(shell):1:22

可以输入包含艺术家或标题的 SortName 字段,但希望避免将其直接放入文档中。

【问题讨论】:

    标签: mongodb sorting


    【解决方案1】:

    如果您希望对大型数据集进行高效排序,并且在 OLTP 风格的工作负载中提供查询服务,那么物化排序键是您的最佳选择,因为您可以在其上放置一个用于排序的索引。 MongoDB 排序运算符本身不支持 ad-hoc、用户定义的排序键。

    如果查询消耗更多时间是可以的,例如对于分析,您可以使用 MongoDB 的 aggregation framework,尤其是两个运算符:

    • $project 允许在聚合管道中创建新字段
    • $ifNull 返回非空值(第一个参数)或后备表达式(第二个参数)

    使用这些,您的排序查询可以写成:

    db.music.aggregate([
      { $project:
        { "Artist": 1,
          "Title": 1,
          "ReleaseYear": 1,
          "SortName": { "$ifNull" : [ "$Artist", "$Title" ] },
        }
      },
      { $sort: { "SortName": 1, "ReleaseYear": 1} }
    ]);
    

    您可以在其中添加任何其他 pipeline steps,例如,首先过滤数据 ($match)。

    【讨论】:

    • 这太棒了!恐怕某处有一个小错误。我得到A pipeline stage specification object must contain exactly one field. 如果我取出, $sort: {} 我得到正确的数据集,新字段SortName
    • 啊,看来$project$sort 需要是聚合数组中的单独元素。有了它就可以完美运行!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-23
    • 2021-11-03
    • 1970-01-01
    • 2020-02-15
    • 1970-01-01
    相关资源
    最近更新 更多