1

私はモンゴコレクションの「本」を持っています。典型的な本は次のとおりです。

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を配列特別な (非正規化/コピー) データを book オブジェクトに直接保存します。そして例えば。クエリはシンプルで超高速です。yearprint_runsBook.last_published_byBook.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 番目のオプション #3 が続くことをお勧めします。

于 2013-06-20T01:36:23.207 に答える