5

を使用して、 ormongoTemplate.find()を呼び出すことができるクエリを指定します。.limit().sort()

.limit()オブジェクトを返しますQueryオブジェクトを
.sort()返しSortます

これを考えると、Query().limit(int).sort() と言えますが、これは目的の操作を実行せず、限られた結果セットを並べ替えるだけです。

.sort() が Sort() を返すため、Query().sort().limit(int) を呼び出すことはできません。

では、Spring Data を使用して、mongoDB シェルに示されているように次のことを実行するにはどうすればよいですか? まだ見つけていない生のクエリを渡す方法があるのではないでしょうか?

必要に応じて Paging インターフェイスを拡張しても問題ありません...まったく役に立たないようです。ありがとう!

> 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 }
4

5 に答える 5

5

これは sping-data-mongodb で行うことができます。並べ替えフィールド (または @Id フィールド) がインデックス化されている場合、Mongo は並べ替え/制限の組み合わせを最適化します。これにより、非常に高速な O(logN) またはそれ以上の結果が得られます。それ以外の場合は、上位 k アルゴリズムを使用し、グローバル ソート ( mongodb sort doc)を回避するため、O(N*logN) ではなく O(N) のままです。これはMkyong の例からのものですが、最初に並べ替えを行い、制限を 1 秒に設定します。

Query query = new Query();
query.with(new Sort(Sort.Direction.DESC, "idField"));
query.limit(1);
MyObject maxObject = mongoTemplate.findOne(query, MyObject.class);
于 2016-10-11T17:01:04.263 に答える
3

通常、集計 SQL クエリで行われることは、NoSQL ストアで (少なくとも) 3 つの方法でアプローチできます。

  • マップ/リデュースで。これは事実上すべてのレコードを通過しますが、より最適化されています (複数のスレッドとクラスターで動作します)。MongoDBのmap/reduce チュートリアルは次のとおりです。

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

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

どちらを選択するかは、この最大値の使用方法によって異なります。めったに実行されない場合 (コーナー レポートなど) は、map/reduce を使用できます。頻繁に使用する場合は、現在の最大値を保存します。

于 2012-03-29T21:40:54.423 に答える
1

私が知っている限り、Mongoは並べ替えと制限を完全にサポートしています: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());
于 2012-03-30T19:56:08.027 に答える
0

集計 $max を使用します。$max は $group ステージでのみ使用可能なアキュムレータ演算子であるため、トリックを行う必要があります。グループ演算子では、任意の定数を _id として使用します。Mongodbサイト
のみ で与えられた例を見てみましょう-

次のドキュメントを含む売上コレクションを考えてみましょう。

{ "_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") }

すべてのアイテムの中で最大の価格を知りたい場合。

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

「_id」の値は「1」であることに注意してください。任意の定数を入れることができます...

于 2015-11-24T14:21:23.437 に答える