1

これはstackoverflowに関する私の最初の質問なので、正しいプロトコルに従っていることを願っています。

CouchDBとNodeJSをベースにした基本的なブラウザゲームを作成しています。私のゲームでは、ユーザーは複数のキャラクターを持つことができます。ユーザーアカウントデータ(メール、本名など)をキャラクターデータに関連付ける必要はほとんどないため、データベース内のキャラクターからプレーヤーを分離することにしました。とにかく、ここに私の問題があります:

プレイヤーが操作するすべてのキャラクターを返すビューを作成できるようにしたいと思います。このドキュメントには「所有者」と呼ばれるプロパティがあります。これを行う最も簡単な方法は、所有者によって分類されたすべての文字のリストを返すビューを作成することだと思います。

これまでの私のコードは次のとおりです。

function(doc){emit(doc.owner、doc); }

私はこのような結果を得ようとしています(これは単純化されています。CouchDBが出力に他のデータを含むことを知っています):

{
    "player1":{
        "character1":{
            "data":{}
        },
        "character2":{
            "data":{}
        }
    },
    "player2":{
        "character1":{
            "data":{}
        },
        "character2":{
            "data":{}
        }
    }
}

キーは一意である必要がありますか?私のコードは私に望ましい結果を与えますか?

私はデータを分離するという考えとは結婚していません。代わりに、ユーザードキュメントの下に文字を配置して、2つのビューを作成することもできます。1つはユーザーアカウントデータのみを出力し、もう1つは文字データのみを出力します。文字データとユーザーデータを省略しますが、それは私には少し厄介なようです。キャラクターデータに固有の他のビューを作成する必要があるかもしれないので、データを分離したいのですが、データベース内のプレーヤーからキャラクターを分離した方が整理されているようです。

関連するメモで、2番目のパラメーターを渡すことによって応答をフィルター処理する方法はありますか?これはビューの効率を損なうものであり、この場合はおそらく一時的なビューを使用する必要があると思います。これに関する私の問題は、このビュー(実際にはデータベース全体)によって大量のデータが返される可能性があることです。これは、特にほとんどのデータを必要としないため、HTTP経由で転送すると非常に遅くなる可能性があります。

別の可能な解決策は、ユーザーが制御する各文字の_idをプロパティとしてユーザーアカウントデータベースに保存することです。これは私には十分に理にかなっているように思えますが、別のオプションがある場合、またはあえて「より良い」オプションが利用可能である場合は、それを聞いてみたいと思います。

この問題の最善の解決策は何でしょうか?

よろしくお願いします。

4

1 に答える 1

4

あなたは正しい道を進んでいます。これをReduceで実行したい場合は、次のマップを定義できます。

function(doc) { 
  var r = {}, c = {}; 
  c[doc._id] = doc;
  r[doc.owner] = c; 
  emit(doc.owner,r); 
}

そしてこれは減らす:

function(k,v,red) {
  var r = {};
  for (var i in v) {
    for (var owner in v[i]) {
      if (!(owner in r)) r[owner] = {};
      for (var character in v[i][owner])
        r[owner][character] = v[i][owner][character];
    }
  }
  return r;
}

これはあなたが要求したものを直接返すはずですが、ほとんど最適ではありません:ビューはMapとReduceの両方の部分の多くのデータを保存する必要があります...

代わりに、次のように、Reduceなしのマップを選択します。

function(doc) {
  emit(doc.owner,null);
}

このマップをで照会するとinclude_docs=true、次のような行が返されます。

[  
  { id : 'charid', key : 'playid', doc : { /* character document */ } },
  ...
]

keyサーバーの負荷は軽く、本当に必要な場合は、結果でを使用して、プレーヤーごとにキャラクターを再グループ化できます。key結果は、、次に。でソートされidます。

とを使用してこのビューをクエリしstartkeyendkey両方をプレーヤーIDと等しくして、プレーヤーが持つすべての文字を取得できます。文字識別子のみが必要な場合は、追加するinclude_docs=falseと重いdoc部分は送信されません。

于 2010-12-13T11:09:05.920 に答える