2012-10-07 23 views
5

との関連性で並べ替え。私は現在、次のクエリを使用しています:は、私は次の形式でのドキュメントのコレクションを持っているのMongoDB

{ "tags": { "$in": ["bar", "hello"] } } 

それは動作します。 「bar」または「hello」とタグ付けされたすべての文書が返されます。

ただし、関連性の高い並べ替え、つまりと一致するタグをより早く検索すると結果が早くなります。たとえば、["bar", "hello", "baz"]とタグ付けされたドキュメントは、クエリ["bar", "hello"]のタグ["bar", "baz", "boo"]とタグ付けされたドキュメントよりも高い結果になるはずです。どうすればこれを達成できますか?

答えて

9

のMapReduceとクライアント側が遅すぎることになるだろう、それをやってdb.eva(一部を除去し、あなたのクライアントは、クライアント側の効果を得るために照会するために使用する言語にそれを翻訳 - あなたを。第一及び第三のパイプラインのメンバーが見て

db.collection.aggregate([ 
    { $match : { "tags": { "$in": ["bar", "hello"] } } }, 
    { $unwind : "$tags" }, 
    { $match : { "tags": { "$in": ["bar", "hello"] } } }, 
    { $group : { _id: "$title", numRelTags: { $sum:1 } } }, 
    { $sort : { numRelTags : -1 } } 
    // optionally 
    , { $limit : 10 } 
]) 

注:集約フレームワーク(MongoDBは2.2で新しい)を使用する必要があります

をそれは次のようになります。これは意図的で必要なものです。手順は次のとおりです。

  1. タグ「bar」または「hello」を持つ文書のみを渡します。タイトルで
  2. タグ配列をほどく(タグのみのタグ要素ごとに1つの文書
  3. パスまさに「バー」または「こんにちは」にスプリットを意味する(すなわち、タグの残りの部分を破棄)
  4. グループ(それができますまた、「$の_id」またはそれは、関連するタグの数
  5. (オプション)リミットの降順で
  6. の並べ替えを持っていた(「バー」と「ハロー」の)どのように多くのタグを追加する元の文書 の任意の他の組み合わせによって戻り値は上位10に設定されます。
+0

{unwind:{"$ tags"}}ではなく{$ unwind: "$ tags"}だと思います –

+0

あなたは何を知っていますか? :) –

+0

私は思います。すばらしい答えbtw--巨大な助け。ありがとう。 –

1

MapReduceをそのような用途に使用する可能性があります。マップステップで各ドキュメントを処理し、クエリに一致するタグの数を調べ、スコアを割り当てます。次に、そのスコアに基づいてソートすることができます。

http://www.mongodb.org/display/DOCS/MapReduce

0

複合体が照会した後に行うべきである何か。サーバー側からdb.eval(クライアントがサポートしている場合)またはクライアント側のみ。ここでは、あなたが探しているものの例です。

あなたが指定したタグを含むすべての投稿を検索し、一致する量に従って並べ替えます。

db.eval(function() { 
    var tags = ["a","b","c"]; 
    return db.posts.find({tags:{$in:tags}}).toArray().sort(function(a,b){ 

     var matches_a = 0; 
     var matches_b = 0; 
     a.tags.forEach(function (tag) { 
      for (t in tags) { 
       if (tag == t) { 
        matches_a++; 
       } else { 
        matches_b++; 
       } 
      } 
     }); 

     b.tags.forEach(function(tag) { 
      for (t in tags) { 
       if (tag == t) { 
        matches_b++; 
       } else { 
        matches_a++; 
       } 
      } 
     }); 
     return matches_a - matches_b; 
    }); 
}); 
+1

これは遅いです大きなコレクションのために、私は別の答えを出そうとします。 – arian

関連する問題