1

我有一个 mongo 收藏“书”。这是一本典型的书:

BOOK

name: 'Test Book'
author: 'Joe Bloggs'
print_runs: [
  {publisher: 'OUP', year: 1981},
  {publisher: 'Penguin', year: 1987},
  {publisher: 'Harper-Collins', year: 1992}
]

我希望能够过滤书籍以仅返回最后一次印刷是在给定日期之后和/或在给定日期之前的书籍......而且我一直在努力寻找可行的查询。任何建议表示赞赏。

4

1 回答 1

5

有几个选项,因为访问数组中的“最后一个”元素并且仅使用findMongoDB 查询中的普通选项进行过滤是困难/不可能的。(不幸的是,您不能$slice使用find)。

  1. 将最新发布publisher的数据存储yearprint_runs数组数据的特殊(非规范化/副本)中,直接在书籍对象上。Book.last_published_by例如Book.last_published_date。查询将非常简单且超级快速。
  2. MapReduce。这很简单,可以发出数组中的最后一个元素,然后“减少”它。您需要在 MapReduce 上进行增量更新以保持准确。
  3. 写一个比较复杂的聚合框架表达式

聚合可能如下所示:

db.so.aggregate({ $project :
    { _id: 1, "print_run_year" : "$print_runs.year" }}, 
    { $unwind: "$print_run_year" }, 
    { $group : { _id : "$_id", "newest" : { $max : "$print_run_year" }}}, 
    { $match : { "newest" : { $gt : 1991, $lt: 2000 } }
})

因为它可能需要一些解释:

  • 它预测和展开每本书的印刷年份。
  • 然后,对_id本书的 ( 进行分组,并创建一个名为的新计算域,newest其中包含最高的印刷年份 (来自投影)。
  • 然后,newest使用$gt和过滤$lt

从效率的角度来看,我建议上面的选项#1 是最好的,其次是 MapReduce,然后是第三个选项#3。

于 2013-06-20T01:36:23.207 回答