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

MongoDBクエリの最適化

    必要なのは、現在の結果セットで一致した用語に関する統計を保持する「ファセット検索」結果です。その後、1つの応答ですべての作業を実行するように「見える」製品もありますが、ほとんどの汎用ストレージエンジンでは複数の操作が必要になることを考慮する必要があります。

    MongoDBを使用すると、2つのクエリを使用して結果自体を取得し、もう1つを使用してファセット情報を取得できます。これにより、SolrやElasticSearchなどの専用検索エンジン製品から得られるファセット結果と同様の結果が得られます。

    ただし、これを効果的に行うには、効果的に使用できる方法でこれをドキュメントに含める必要があります。トークン化されたデータの配列を使用することは、必要なものに非常に効果的な形式です。

     {
         "otherData": "something",
         "facets": [
             "country:UK",
             "city:London-UK",
             "genre:Student"
         ]
     }
    

    したがって、「ファクト」はドキュメント内の単一のフィールドであり、複数の場所にあるわけではありません。これにより、インデックス作成とクエリが非常に簡単になります。次に、結果全体を効果的に集計し、各ファセットの合計を取得できます。

    User.aggregate(
        [
            { "$unwind": "$facets" },
            { "$group": {
                "_id": "$facets",
                "count": { "$sum": 1 }
            }}
        ],
        function(err,results) {
    
        }
    );
    

    または、より理想的には、 $matchにいくつかの基準があります

    User.aggregate(
        [
            { "$match": { "facets": { "$in": ["genre:student"] } } },
            { "$unwind": "$facets" },
            { "$group": {
                "_id": "$facets",
                "count": { "$sum": 1 }
            }}
        ],
        function(err,results) {
    
        }
    );
    

    最終的に次のような応答を返します:

    { "_id": "country:FR", "count": 50 },
    { "_id": "country:UK", "count": 300 },
    { "_id": "city:London-UK", "count": 150 },
    { "_id": "genre:Student": "count": 500 }
    

    このような構造は、データがハイフン「-」で一貫して区切られているため、個別の「国」や「国」に属する「都市」などを簡単にトラバースして検査できます。

    配列内のドキュメントをマッシュアップしようとするのは悪い考えです。 BSONのサイズ制限も尊重されます。16MBの結果をマッシュアップすると(特にドキュメントコンテンツを保持しようとしている場合)、応答で超過する可能性があります。

    そのようなクエリから結果の「全体の数」を取得するような単純なものについては、特定のファセットタイプの要素を合計するだけです。または、同じクエリ引数を.count()に発行します。 操作:

    User.count({ "facets": { "$in": ["genre:Student"] } },function(err,count) {
    
    });
    

    ここで述べたように、特に結果の「ページング」を実装する場合、「結果カウント」、「ファセットカウント」、および実際の「結果のページ」を取得する役割はすべて、サーバーへの「個別の」クエリに委任されます。

    >

    これらの各クエリをサーバーに並行して送信し、構造を組み合わせて、この種の応答を提供する検索エンジン製品の1つからのファセット検索結果によく似たテンプレートまたはアプリケーションにフィードすることに問題はありません。

    結論

    したがって、ドキュメントに何かを入れて、ファセットを1か所にマークします。トークン化された文字列の配列は、この目的に適しています。また、 $inなどのクエリフォームでもうまく機能します および$all ファセット選択の組み合わせの「または」または「and」条件のいずれか。

    認識された階層構造に一致させるためだけに結果をマッシュアップしたり、追加をネストしたりするのではなく、受け取った結果をトラバースして、トークンに単純なパターンを使用します。とても簡単です

    コンテンツのページクエリを、ファセットまたは全体のカウントに対する個別のクエリとして実行します。配列内のすべてのコンテンツをプッシュしてから、カウントを取得するためだけに制限しようとしても意味がありません。同じことを行うRDBMSソリューションにも同じことが当てはまり、ページング結果のカウントと現在のページは別々のクエリ操作になります。

    MongoDBブログには、MongoDBを使用したファセット検索に関する詳細情報が記載されており、他のオプションについても説明されています。 mongoconnectorまたは他のアプローチを使用した外部検索ソリューションとの統合に関する記事もあります。




    1. WindowsにMongoDBをインストールする

    2. javascriptでISO日付オブジェクトを作成します

    3. MongoEngineを使用して並べ替えますか?

    4. ハウツー:ClouderaManagerを使用してClouderaSearchをクラスターに追加する