2012-03-29 3 views
4

mongoTemplate.find()を使用して、私は.limit()または.sort()を呼び出すことが可能なクエリを指定します。SpringデータMongodbを使用すると、コレクション全体をプルしたり反復したりせずに、フィールドの最大値を取得できますか?

.limit()Queryオブジェクト
.sort()

がこれを考えるとSortオブジェクトを返し、私は(クエリを言うことができる)リミット( int).sort()ですが、これは目的の操作を実行しません。制限された結果セットをソートするだけです。

私は(クエリを呼び出すことはできません)。ソート()。リミット(int型)のいずれか.sort以来()(ソートを返す)

そうにMongoDBに示すように、私は次のように実行するのですか、春のデータを使用してシェル?たぶん、私がまだ見つけていない生のクエリを渡す方法がありますか?

必要ならば、私はページングインターフェイスを拡張しても大丈夫でしょう...ちょっと役に立たないようです。ありがとう!

> j = { order: 1 } 
{ "order" : 1 } 
> k = { order: 2 } 
{ "order" : 2 } 
> l = { order: 3 } 
{ "order" : 3 } 
> db.test.save(j) 
> db.test.save(k) 
> db.test.save(l) 
> db.test.find() 
{ "_id" : ObjectId("4f74d35b6f54e1f1c5850f19"), "order" : 1 } 
{ "_id" : ObjectId("4f74d3606f54e1f1c5850f1a"), "order" : 2 } 
{ "_id" : ObjectId("4f74d3666f54e1f1c5850f1b"), "order" : 3 } 
> db.test.find().sort({ order : -1 }).limit(1) 
{ "_id" : ObjectId("4f74d3666f54e1f1c5850f1b"), "order" : 3 } 
+0

残念ながら、I – ControlAltDel

+0

[mongodbでfindOneを使ってmax idの要素を取得する]の可能な複製(http://stackoverflow.com/questions/22118210/using-findone-in) -mongodb-to-get-element-with-max-id) – Pynchia

答えて

3

通常、集計SQLクエリで行われ、物事は、(少なくとも)に近づくことができNoSQLの店で三つの方法:地図と

  • /縮小します。これはすべてのレコードを効果的に処理しますが、より最適化されています(複数のスレッドとクラスタで動作)。 MongoDBの場合はmap/reduce tutorialです。

  • 各インサートの最大値を事前に計算して別々に保管してください。したがって、レコードを挿入するたびに前の最大値と比較し、大きい場合はdbの最大値を更新します。

  • メモリ内のすべてを取り出し、コード内で計算します。それが最も簡単な解決策です。小さなデータセットではうまくいくでしょう。

この最大値を使用するかどうかは、この最大値の使用方法によって異なります。ごくまれに実行された場合、たとえばコーナーレポートの場合は、map/reduceを使用できます。頻繁に使用される場合は、現在の最大値を保存してください。

+0

私はまだmongoをかなり新しくしているので、map/reduceで作業する機会はまだありませんでしたが、シェルで利用可能なものがコードに当てはまらない限り、Q&Aに例示されているようにmongoでこれを直接実行しますか? そこにあるものをSpring Dataに翻訳する方法はありませんか? map/reduceはまだコレクションの完全なフェッチを必要とし、多くのノードを持たない状況では本当にあなたを買わないようです。 私の仮定は間違っていますか?これはまだ私が問題に持っている最善のアプローチですか? –

1

は、私の知る限りモンゴは完全にソートその後、制限サポート承知していますよう:http://www.mongodb.org/display/DOCS/Sorting+and+Natural+Order

がを減らすマップを経由して最大/最小を見ると非常に遅くなるだろうし、すべてのコストで回避する必要があります。

私はSpring Dataについて何も知らないが、Morphiaにクエリを助けることを勧めている。それ以外の場合は、Javaドライバの基本的な方法は次のようになります。

DBCollection coll = db.getCollection("..."); 

DBCursor curr = coll.find(new BasicDBObject()).sort(new BasicDBObject("order", -1)) 
.limit(1); 

if (cur.hasNext()) 
    System.out.println(cur.next()); 
0

集約を使用する$ max。 $ maxは$ groupステージでのみ利用可能なアキュムレータ演算子なので、あなたはトリックをする必要があります。 グループ演算子では、任意の定数を_idとして使用します。あなたはすべての項目のうち、最大の価格を知りたい場合は

{ "_id" : 1, "item" : "abc", "price" : 10, "quantity" : 2, "date" : ISODate("2014-01-01T08:00:00Z") } 
{ "_id" : 2, "item" : "jkl", "price" : 20, "quantity" : 1, "date" : ISODate("2014-02-03T09:00:00Z") } 
{ "_id" : 3, "item" : "xyz", "price" : 5, "quantity" : 5, "date" : ISODate("2014-02-03T09:05:00Z") } 
{ "_id" : 4, "item" : "abc", "price" : 10, "quantity" : 10, "date" : ISODate("2014-02-15T08:00:00Z") } 
{ "_id" : 5, "item" : "xyz", "price" : 5, "quantity" : 10, "date" : ISODate("2014-02-15T09:05:00Z") } 

: -
だけMongodb siteで与えられた例を取ることができます

は、以下の書類と販売コレクションを考えてみましょう。

db.sales.aggregate(
    [ 
    { 
     $group: 
     { 
      _id: "1", //** This is the trick 
      maxPrice: { $max: "$price" } 
     } 
    } 
    ] 
) 

"_id" の値があることに注意してください - それは "1" です。あなたは任意の定数を置くことができます...

1

これはsping-data-mongodbで行うことができます。 Mongoはソートフィールドがインデックス付けされている場合(または@Idフィールドの場合)ソート/リミットの組み合わせを最適化します。それはトップ-Kアルゴリズムを使用し、グローバルソート(mongodb sort doc)。これはMkyong's exampleからですが、私は最初の並べ替えを行うと、1秒に制限を設定を避けることができますので、それ以外の場合は、まだかなり良いです。

Query query = new Query(); 
query.with(new Sort(Sort.Direction.DESC, "idField")); 
query.limit(1); 
MyObject maxObject = mongoTemplate.findOne(query, MyObject.class); 
関連する問題