1

私は以下の書類を持っています。キーワードのタイムスタンプ位置。

{
  _id: willem-aap-1234,
  keyword:aap,
  position: 10,
  profile: { name: willem },
  created_at: 1234
},
{
  _id: willem-aap-2345,
  keyword:aap,
  profile: { name: willem },
  created_at: 2345
},
{
  _id: oliver-aap-1235,
  keyword:aap,
  profile: { name: oliver },
  created_at: 1235
},
{
  _id: oliver-aap-2346,
  keyword:aap,
  profile: { name: oliver },
  created_at: 2346
}

profile.name ごとに最新のキーワードを見つけるには、次のようにします。

map: function(doc) {
if(doc.profile)
    emit(
        [doc.profile.name, doc.keyword, doc.created_at], 
        { keyword : doc.keyword, position : doc.position, created_at: doc.created_at }
    );
}

reduce: function(keys, values, rered) {
  var r = values[0];
  for (var i=1; i<values.length; i++)
    if (r.created_at < values[i].created_at)
      r = values[i];
  return r;
}

そして、データベースにクエリを実行します

reduce : true,
group_level : 2,
startkey : [aname],
endkey : [aname,{}]

これにより、aname という名前のプロファイルの最新のドキュメントが表示されます。

しかし今、キーワードごとに最新のすべてのドキュメントを数え、その位置を合計したいと考えています。これを map/reduce のみで実行しようとしても、頭に浮かびません。

私のユーザーケースは次のとおりです。

  1. profile.user ごと、キーワードごとに最新のドキュメントを検索
  2. キーワードごとの固有の profile.name の数を数えます
  3. キーワードごとに、最新のドキュメントの位置を合計します

私がそれを機能させる唯一の方法は、次のリスト関数を使用することです:

function(head, req) {
  var row;
  var counts = {};
  while (row = getRow()) {
    var v = row.value;
    var k = v.keyword;

    if (v.position) {
      if (!counts[k])
        counts[k] = { 
          position : 0,
          count : 0
        }
      counts[k].position += v.position;
      counts[k].count++;
    }
  }

  return JSON.stringify(counts);
}

map/reduce のみを使用して、これを行うためのより良い方法を考えられる人はいますか?

ありがとう

4

1 に答える 1

0

一部の部分の意味はまだ少し曇っています (たとえば、「位置」とは何ですか?)。

しかし、純粋に正式な観点から見ると、リストは にインデックスをkeyword 作成し、マップは にインデックスを作成したよう[profile, keyword, timestamp]です。

本当に異なるインデックスが必要な場合は、インデックスごとに 1 つずつ、複数のマップが必要です。唯一の例外は、既に にマップがある場合です[a,b,c]。「グループ レベル」を変更して、 と の 2 つの他のインデックスを取得でき[a,b]ます[a]

于 2013-03-11T19:50:48.747 に答える