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

個別のカウントでソートするMongoクエリ

    MongoDBにはまだこれを行うための本当に効率的な演算子がないため、これは実際には(まだ)複数のクエリで最も適切に処理されます。

    MongoDB 3.2でもこのようなことができますが、明らかな「キャッチ」があります:

    db.Books.aggregate([
        { "$group": {
            "_id": "$company",
            "count": { "$sum": 1 },
            "urls": {
                "$push": "$url"
            }
        }},
        { "$sort": { "count": -1 } },
        { "$limit": 10 },
        { "$project": {
            "count": 1,
            "urls": { "$slice": ["$urls",0, 3] }
        }}
    ])
    

    そして明らかな問題は、何があっても、すべてを追加していることです。 グループ化された配列への「url」コンテンツの。これは、BSONの制限である16MBを超える可能性があります。そうではないかもしれませんが、「3つ」だけが必要な場合に「すべて」のコンテンツを追加するのはまだ少し無駄です。

    そのため、それでも、上位10件の結果のそれぞれで「URL」を個別に実際にクエリする方がおそらくより実用的です。

    これは、以下を示すnode.jsのリストです。

    var async = require('async'),
        mongodb = require('mongodb'),
        MongoClient = mongodb.MongoClient;
    
    MongoClient.connect("mongodb://localhost/test",function(err,db) {
    
        if (err) throw err;
    
        // Get the top 10
        db.collection("Books").aggregate(
            [
                { "$group": {
                    "_id": "$company",
                    "count": { "$sum": 1 }
                 }},
                 { "$sort": { "count": -1 } },
                 { "$limit": 10 }
            ],function(err,results) {
                if (err) throw err;
    
                // Query for each result and map query response as urls
                async.map(
                    results,
                    function(result,callback) {
                        db.collection("Books").find({ 
                           "company": result.company 
                        }).limit(3).toArray(function(err,items) {
                            result.urls = items.map(function(item) { 
                                return item.url;
                            });
                            callback(err,result);
                        })
                    },
                    function(err,results) {
                        if (err) throw err;
                        // each result entry has 3 urls
                    }
                );
            }
         )
    
    });
    

    はい、それはデータベースへのより多くの呼び出しですが、実際にはわずか10 したがって、実際には問題ではありません。

    本物 この解決策は、SERVER-9377で説明されています-$pushまたは$maxを拡張して、「top」を収集できるようにします"$groupフェーズの_idキーごとにN個の値 。これは有望な「進行中」ステータスであるため、積極的に取り組んでいます。

    それが解決されると、単一の集計ステートメントが実行可能になります。それ以降、最初の$pushで結果の「url」を「制限」できるようになります。 事後に3つを除くすべてを削除するのではなく、3つのエントリだけに変更します。




    1. (sails js)waterlineを介してmongodbデータベースの配列に値をプッシュします

    2. Mongo C#ドライバー-ネストを使用して動的にフィルターを構築する

    3. ハウツー:HBaseバルクローディングを使用する理由とその理由

    4. Laravel Echo Server、Redis、Socket.IO:それらを機能させることができないようです