web-dev-qa-db-ja.com

Java、MongoDB:膨大なコレクションを繰り返しながらすべてのオブジェクトを更新するにはどうすればよいですか?

それぞれ20フィールドの約100万件のレコードのコレクションがあります。このflagフィールドにランダムに1または2を割り当てて、すべてのレコード(ドキュメント)の整数flagフィールドを更新する必要があります。コレクション全体でカーソルを繰り返しながらこれを行うにはどうすればよいですか?更新できるようにするためだけに、MongoDBによって既に見つかったオブジェクトを2回検索するのは良い考えではないようです。

  DBCursor cursor = coll.find();
  try {
     while(cursor.hasNext()) {
    BasicDBObject obj = (BasicDBObject) cursor.next();
    ...
    coll.update(query,newObj)

     }
  } finally {
     cursor.close();
  }

巨大なMongoDBコレクションのすべてのドキュメントのフィールドを異なる値で効率的に更新するにはどうすればよいですか?

15
Anton Ashanin

あなたのアプローチは基本的に正しいです。ただし、そのようなコレクションを「巨大な」とは見なしません。シェルから同様の何かを実行できます。

_coll.find({}).forEach(function (doc) {
    doc.flag = Math.floor((Math.random()*2)+1);
    coll.save(doc);
 });
_

MongoDBのバージョン、構成、および負荷に応じて、これには数分から数時間かかる場合があります

この更新を一括で実行する場合は、クエリドキュメントでcoll.find({"aFiled" : {$gt : minVal}, "aFiled" : {$lt : maxVal}})などの条件を使用します。

21
Ori Dar

@oridに触発された私自身の質問に対する私の解決策:

public void tagAll(int min, int max) {
    int rnd = 0;
    DBCursor cursor = this.dataColl.find();
    try {
        while (cursor.hasNext()) {
            BasicDBObject obj = (BasicDBObject) cursor.next();
            rnd = min + (int) (Math.random() * ((max - min) + 1));
            obj.put("tag", rnd);
            this.dataColl.save(obj);
        }
    } finally {
        cursor.close();
    }
}
5
Anton Ashanin