0

我知道在对集合执行 find() 时可以使用 $orderBy。但是我的收藏包含其他对象,我该如何对这些对象进行排序?例如:

books: [{
  title: 'book 1',
  authors: [
     { name: 'jim' },
     { name: 'bob' },
  ]
}, {
  title: 'book 2',
  authors: [
     { name: 'steve' },
     { name: 'joe' },
  ]
}];

我想做 db.collections.find(); 并让它按顺序返回所有书籍(我知道如何使用 $orderBy,但我也希望对作者进行排序。

4

2 回答 2

2

诀窍是在写入时间而不是读取时间对文档进行排序。

如前所述,您要求 MongoDB 在文档到达您的应用程序之前对其进行修改。Mongo 不喜欢在没有特定命令的情况下修改文档。主要的选择是聚合、map reduce 和投影。这些都不是特别适合您的问题:

  • 聚合可能比您需要的更复杂,请参阅此处的选项的其他答案。
  • Map Reduce 类似于 Aggregation,但更复杂。
  • Query-time Projection可以过滤返回的字段,但没有排序选项。

相反,以您想要检索它们的方式存储文档。最初编写或更新文档时,请在$sort数组上使用数组更新运算符authors。存储的BSON 对象将保留排序,因此在检索文档时将对数组进行排序。

这使得读取比使用聚合框架或 map reduce 更简单、更快。

于 2013-10-15T18:16:54.970 回答
1

我不完全确定你需要什么。MongoDB 返回完整的文档,因此所有书籍的作者列表必须在客户端或使用聚合框架编译。它不能使用简单的查询来完成,因为它需要在排序操作之前进行投影。

此外,您可能希望有一个不同的作者列表,否则某些作者将在列表中出现数十次。

使用聚合框架,您可以这样做:

db.books.aggregate(
   {"$unwind" : "$authors"},              // unwind the array
   {$group : {"_id" : "$authors.name"} }, // distinct
   {$sort : {"_id" : 1}});                // the actual sort
于 2013-10-15T16:15:20.657 回答