15

ドキュメントを含むmongoコレクションがあります。すべてのドキュメントには、0 または 1 のフィールドが 1 つあります。データベースから 1000 レコードをランダムにサンプリングし、そのフィールドを持つドキュメントの数を 1 としてカウントする必要があります。このサンプリングを 1000 回行う必要があります。どうすればいいのですか ?

4

5 に答える 5

11

MongoDB 3.0 以前では、SQL 時代の古いトリックを使用しています (ウィキペディアがランダム ページ機能に使用していると思います)。ランダム化する必要があるすべてのオブジェクトに 0 から 1 までの乱数を格納します。そのフィールドを "r" と呼びましょう。次に、「r」にインデックスを追加します。

db.coll.ensureIndex(r: 1);

ランダムな x オブジェクトを取得するには、次を使用します。

var startVal = Math.random();
db.coll.find({r: {$gt: startVal}}).sort({r: 1}).limit(x);

これにより、単一の検索クエリでランダムなオブジェクトが得られます。必要に応じて、これはやり過ぎかもしれませんが、時間の経過とともに多くのサンプリングを行う場合、これはバックエンドに負荷をかけずに非常に効率的な方法です。

于 2012-11-12T10:24:16.570 に答える
4

mongoシェルの例を次に示します。 のコレクションcollnameと の対象の値を想定していthefieldます。

var total = db.collname.count();
var count = 0;
var numSamples = 1000;

for (i = 0; i < numSamples; i++) {
    var random = Math.floor(Math.random()*total);
    var doc = db.collname.find().skip(random).limit(1).next();
    if (doc.thefield) {
        count += (doc.thefield == 1);
    }
}
于 2012-10-01T11:57:01.303 に答える
1

これで@Stenniesの回答に対するコメントを編集するつもりでしたが、膨大な量のレコードをスキップする場合は、代わりにここで個別の自動インクリメントIDインデックスを使用することもできます(ここで大きな話をします)。

コレクションのn番目のレコードを見つけようとしていたこの質問によく似た、別の質問に対する別の回答を書きました。

php mongodbはコレクション内のn番目のエントリを見つけます

私の回答の後半では、基本的に、この問題に対処するための 1 つの潜在的な方法について説明しています。もちろん、ランダムな行を取得するには、1000回ループする必要があります。

于 2012-10-01T14:03:15.317 に答える
0

mongoengine を使用している場合は、SequenceField を使用して増分カウンターを生成できます。

class User(db.DynamicDocument):
    counter = db.SequenceField(collection_name="user.counters")

次に、たとえば 100 個のランダムなリストを取得するには、次のようにします。

def get_random_users(number_requested):
    users_to_fetch = random.sample(range(1, User.objects.count() + 1), min(number_requested, User.objects.count()))
    return User.objects(counter__in=users_to_fetch)

どこに電話するか

get_random_users(100)
于 2015-04-17T23:31:11.540 に答える