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

Aggregationパイプライン、MapReduce、またはrunCommandに保存されているJavaScript関数を使用する

    system.jsに保存する関数 $whereなどの「JavaScript」処理ステートメントで使用できます 演算子とmapReduce _idで参照できます 値が割り当てられました。

    db.system.js.save({ 
       "_id": "squareThis", 
       "value": function(a) { return a*a } 
    })
    

    そして、「サンプル」コレクションに挿入されたいくつかのデータ:

    { "_id" : ObjectId("55aafd2bacbed38e06f9eccf"), "a" : 1 }
    { "_id" : ObjectId("55aafea6acbed38e06f9ecd0"), "a" : 2 }
    { "_id" : ObjectId("55aafeabacbed38e06f9ecd1"), "a" : 3 }
    

    次に:

    db.sample.mapReduce(
        function() {
           emit(null, squareThis(this.a));
        },
        function(key,values) {
            return Array.sum(values);
        },
        { "out": { "inline": 1 } }
     );
    

    与える:

       "results" : [
                {
                        "_id" : null,
                        "value" : 14
                }
        ],
    

    または$where

    db.sample.find(function() { return squareThis(this.a) == 9 })
    { "_id" : ObjectId("55aafeabacbed38e06f9ecd1"), "a" : 3 }
    

    ただし、「どちらでもない」場合は、データベースdbなどのグローバルを使用できません。 参照または他の関数。両方の$where およびmapReduce ドキュメントには、ここでできることの限界に関する情報が含まれています。したがって、「別のコレクションのデータを検索する」などの操作を行うと思った場合は、「許可されていない」ため、忘れることができます。

    すべて MongoDBコマンドアクションは実際には とにかく「内部」での「runCommand」アクションの呼び出し。ただし、そのコマンドが実際に実行しているのが「JavaScript処理エンジンの呼び出し」でない限り、使用法は関係ありません。とにかくこれを行うコマンドは、mapReduceのようにほんのわずかです。 、group またはeval 、そしてもちろん、$whereを使用した検索操作 。

    集約フレームワークはしません なんらかの方法でJavaScriptを使用してください。他の人がこのような発言をしたのと同じように、あなたは誤解しているかもしれません。それはあなたが思っていることをしません:

    db.sample.aggregate([
        { "$match": {
            "a": { "$in": db.sample.distinct("a") }
        }}
    ])
    

    つまり、"内部で実行されていない " 集約パイプラインではなく、その.distinct()の「結果」 パイプラインがサーバーに送信される前に、呼び出しが「評価」されます。とにかく外部変数の場合と同じように:

    var items = [1,2,3];
    db.sample.aggregate([
        { "$match": {
            "a": { "$in": items }
        }}
    ])
    

    どちらも基本的に同じ方法でサーバーに送信します:

    db.sample.aggregate([
        { "$match": {
            "a": { "$in": [1,2,3] }
        }}
    ])
    

    したがって、集約パイプラインでJavaScript関数を「呼び出す」ことは「不可能」であり、system.jsに保存されたものから一般的に結果を「渡す」ことは実際にはありません。 。 「コード」は「クライアントにロード」する必要があり、JavaScriptエンジンだけが実際にそれを使って何でもできます。

    集約フレームワークでは、利用可能なすべての「演算子」は、mapReduceに提供される「自由形式」のJavaScript解釈とは対照的に、実際にはネイティブにコード化された関数です。 。したがって、「JavaScript」を記述する代わりに、演算子自体を使用します。

    db.sample.aggregate([
        { "$group": {
            "_id": null,
            "sqared": { "$sum": {
               "$multiply": [ "$a", "$a" ]
            }}
        }}
    ])
    
    { "_id" : null, "sqared" : 14 }
    

    そのため、system.jsに保存されている関数で実行できることには制限があり、実行したいことは次のいずれかである可能性があります。

    • 別のコレクションのデータにアクセスするなど、許可されていません
    • ロジックは一般的に自己完結型であるため、実際には必要ありません
    • または、とにかくクライアントロジックまたは他の異なる形式で実装した方がよいでしょう

    私が本当に考えることができる唯一の実用的な使用法は、他の方法では実行できない多数の「mapReduce」操作があり、すべての内部で維持するのではなく、サーバーに保存するだけのさまざまな「共有」機能があることです。 mapReduce関数呼び出し。

    しかし、繰り返しになりますが、集計フレームワークに対するmapReduceの90%の理由は、通常、コレクションの「ドキュメント構造」が適切に選択されておらず、検索と分析のためにドキュメントをトラバースするためにJavaScript機能が「必要」であるためです。

    したがって、許可された制約の下で使用できますが、ほとんどの場合、これをまったく使用しないでください。ただし、そもそもこの機能が必要であると思わせる他の問題を修正してください。




    1. MongoDB $ log10

    2. Laravel5.1セッションとSocket.IO+Redis-ログインした(既知の)ユーザーとユーザーのグループに通知を送信する

    3. フィールドのタイプを変更するにはどうすればよいですか?

    4. 公共部門向けのAzure政府をサポートする最初のMongoDBホスティングDBaaS