sql >> データベース >  >> NoSQL >> MongoDB

MongoDB:100のコレクションから10のランダムなドキュメントを見つける方法は?

    これはずっと前に答え​​られ、それ以来、MongoDBは大きく進化しました。

    別の回答に投稿されているように、MongoDBは、バージョン3.2以降、AggregationFramework内でのサンプリングをサポートするようになりました。

    これを行う方法は次のとおりです。

    db.products.aggregate([{$sample: {size: 5}}]); // You want to get 5 docs
    

    または:

    db.products.aggregate([
      {$match: {category:"Electronic Devices"}}, // filter the results
      {$sample: {size: 5}} // You want to get 5 docs
    ]);
    

    ただし、$sample演算子についていくつかの警告があります。

    (2017年11月6日現在、最新バージョンは3.4です)=>これらのいずれかが満たされていない場合:

    • $sampleはパイプラインの最初の段階です
    • Nは、コレクション内のドキュメント全体の5%未満です
    • コレクションには100を超えるドキュメントが含まれています

    上記の条件のいずれかが満たされない場合、$ sampleはコレクションスキャンを実行し、続いてランダムソートを実行してN個のドキュメントを選択します。

    $ match

    を使用した最後の例のように

    古い答え

    いつでも実行できます:

    db.products.find({category:"Electronic Devices"}).skip(Math.random()*YOUR_COLLECTION_SIZE)
    

    ただし、順序はランダムではなく、2つのクエリ(YOUR_COLLECTION_SIZEを取得するために1つのカウント)またはその大きさを見積もる必要があります(約100レコード、約1000、約10000 ...)

    ランダムな番号ですべてのドキュメントにフィールドを追加し、その番号でクエリを実行することもできます。ここでの欠点は、同じクエリを実行するたびに同じ結果が得られることです。これを修正するには、いつでも制限とスキップ、または並べ替えで遊ぶことができます。レコードをフェッチするたびにこれらのランダムな数値を更新することもできます(より多くのクエリを意味します)。

    --Mongoose、Mondoid、または直接Mongo Driverを特定の言語で使用しているかどうかはわかりません。そのため、mongoシェルについてすべて説明します。

    したがって、たとえば、製品レコードは次のようになります。

    {
     _id: ObjectId("..."),
     name: "Awesome Product",
     category: "Electronic Devices",
    }
    

    使用することをお勧めします:

    {
     _id: ObjectId("..."),
     name: "Awesome Product",
     category: "Electronic Devices",
     _random_sample: Math.random()
    }
    

    次に、次のことができます:

    db.products.find({category:"Electronic Devices",_random_sample:{$gte:Math.random()}})
    

    次に、定期的に実行して、ドキュメントの_random_sampleフィールドを定期的に更新できます。

    var your_query = {} //it would impact in your performance if there are a lot of records
    your_query = {category: "Electronic Devices"} //Update 
    //upsert = false, multi = true
    db.products.update(your_query,{$set:{_random_sample::Math.random()}},false,true)
    

    または、一部のレコードを取得するたびに、それらすべてまたは一部(取得したレコードの数に応じて)を更新できます。

    for(var i = 0; i < records.length; i++){
       var query = {_id: records[i]._id};
       //upsert = false, multi = false
       db.products.update(query,{$set:{_random_sample::Math.random()}},false,false);
    }
    

    編集

    に注意してください
    db.products.update(your_query,{$set:{_random_sample::Math.random()}},false,true)
    

    クエリに一致するすべての製品が同じで更新されるため、うまく機能しません。 乱数。最後のアプローチの方がうまく機能します(ドキュメントを取得するときに一部のドキュメントを更新します)



    1. Redisのデータディレクトリはどこにありますか?

    2. 一度に多くのリクエストがあった場合、Redisは更新されません

    3. Mongo DBでの保存と挿入の違いは何ですか?

    4. 時間の経過に伴うRedigoScanStructエラー