我有一个mongo系列'书籍'。这是一本典型的书:
BOOK
name: 'Test Book'
author: 'Joe Bloggs'
print_runs: [
{publisher: 'OUP', year: 1981},
{publisher: 'Penguin', year: 1987},
{publisher: 'Harper-Collins', year: 1992}
]
我希望能够过滤书籍,只返回最后打印运行的书籍是在给定日期之后,和/或在给定日期之前......我一直在努力找到一个可行的查询。任何建议表示赞赏。
答案 0 :(得分:5)
有一些选项,因为访问数组中的“last”元素并且只使用MongoDB查询中的普通find
选项进行过滤很难/不可能。 (很遗憾,您不能$slice
使用find
)。
publisher
和year
存储在print_runs
数组和中直接存储在本书的特殊(非规范化/复制)数据中宾语。例如Book.last_published_by
和Book.last_published_date
。查询很简单,也很快。聚合可能如下所示:
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。