2

Mongoドキュメントの状態:

Mongoマルチキー機能は、値の配列に自動的にインデックスを付けることができます。

それはすばらしい。しかし、マルチキーに基づいて並べ替えるのはどうですか?より具体的には、配列の一致率に従ってコレクションを並べ替える方法は

たとえば、[ 'fruit', 'citrus' ]次のようなパターンとコレクションがあります。

{
    title: 'Apples',
    tags: [ 'fruit' ]
},

{
    title: 'Oranges',
    tags: [ 'fruit', 'citrus' ]
},

{
    title: 'Potato',
    tags: [ 'vegetable' ]
}

次に、タグパターンに対する各エントリの一致率に従ってコレクションを並べ替えます。オレンジが最初に来て、リンゴが次に来て、ジャガイモが最後に来なければなりません。

それを行うための最も効率的で簡単な方法は何ですか?

4

2 に答える 2

4

MongoDB 2.1以降、集約フレームワークを使用して同様の計算を実行できます。構文は次のようなものです

db.fruits.aggregate(
     {$match : {tags : {$in : ["fruit", "citrus"]}}}, 
     {$unwind : "$tags"}, 
     {$group : {_id : "$title", numTagMatches : {$sum : 1}}}, 
     {$sort : {numTagMatches : -1}} )

これは

 {
   "_id" : "Oranges",
   "numTagMatches" : 2
 },
 {
   "_id" : "Apples",
   "numTagMatches" : 1
 }

これは、2つの理由から、map-reduceメソッドよりもはるかに高速である必要があります。まず、実装がjavascriptではなくネイティブC++であるためです。次に、「$ match」はまったく一致しないアイテムを除外するため(これが目的でない場合は、「$ match」の部分を省略して、「$sum」の部分を次のいずれかに変更できます)タグが「フルーツ」または「柑橘類」に等しいか、どちらにも等しくないかどうかに応じて、1または0)。

ここでの唯一の注意点は、mongo2.1はまだ本番環境に推奨されていないということです。本番環境で実行している場合は、2.2を待つ必要があります。ただし、自分で実験しているだけの場合は、集約フレームワークのパフォーマンスが向上するため、2.1を試してみることができます。

于 2012-03-26T15:29:34.087 に答える
2

: 以下の説明は、Mongo 2.0 以前の場合に必要です。それ以降のバージョンでは、新しい集計フレームワークを検討する必要があります。

索引付けする入力文のあいまい一致を試みるときに、同様のことを行います。map reduce を使用して、一致するたびにオブジェクト ID を発行し、それらを合計することができます。次に、結果をクライアントにロードし、最初に最大値で並べ替える必要があります。

db.plants.mapReduce(
    function () {
        var matches = 0;
        for (var i = 0; i < targetTerms.length; i++) {
            var term = targetTerms[i];
            for (var j = 0; j < this.tags.length; j++) {
                matches += Number(term === this.tags[j]);
            }   
        }   
        emit(this._id, matches);
    },  

    function (prev, curr) {
        var result = 0;
        for (var i = 0; i < curr.length; i++) {
            result += curr[i];
        }   
        return result;
    },  

    {   
        out: { inline: 1 },

        scope: {
            targetTerms: [ 'fruit', 'oranges' ],
        }   
    }   
);

上記の map 関数で使用できるように、 map reduce 呼び出し['fruit', 'citrus' ]のパラメーターを使用して入力値を渡す必要があります。scope{targetTerms: ['fruit', 'citrus' ]}

于 2012-03-23T17:47:34.813 に答える