7

私はCouchApp(ミドルウェアなし)の最良のアプローチを決定しようとしています。私の考えと類似しているので、CouchDBにスタックオーバーフローページが保存されていると仮定しましょう。本質的に、それは一番上の実際の質問、答え、そしてコメットで構成されています。それらは基本的に3つの層です。

保存には2つの方法があります。データの適切なJSON表現を含む単一のドキュメント内にあるか、エントリの各部分を後でビューを介してそれらを組み合わせた個別のドキュメント内に保存します(これと同様:http ://www.cmlenz.net/archives/2007/ 10 / couchdb-joins

さて、どちらのアプローチも問題ないかもしれませんが、私の現在の観点からは、どちらにも大きな欠点があります。ビジーなドキュメント(複数のユーザーによる多くの変更が予想されます)を署名エンティティとして保存すると、競合が発生します。ユーザーAが自分の変更をドキュメントに保存する場合、ユーザーBは更新の入力を終了すると、競合エラーを受け取ります。再試行する前にドキュメントを再ダウンロードすることで、ユーザーの知らないうちにこれを修正できると想像できます。

マルチユーザー更新の問題

しかし、ドキュメントがかなり大きい場合はどうなりますか?特に、多くのユーザーが同時にドキュメントを更新するために再試行プロセスを複数回実行する必要がある場合は、保存プロセスにかなりの遅延が発生するため、時間の経過とともにかなり大きくなります。

私が見るもう一つの問題は編集です。すべてのユーザーが自分の投稿を編集できるようにする必要があります。現在、それらが1つのドキュメント内に格納されている場合、確実な認証ハンドラーを作成するのは難しいかもしれません。

では、複数のドキュメントのアプローチを見てみましょう。質問、回答、コメントはそれぞれのドキュメントに保存されます。利点:ドキュメントの実際の所有者のみが競合を引き起こす可能性がありますが、これはあまり頻繁には発生しません。全体のかなり小さな要素なので、再ダウンロードにはそれほど時間はかかりません。さらに、認証ルーチンは非常に簡単に実現できるはずです。

これが欠点です。単一のドキュメントは、クエリと表示が非常に簡単です。並べ替えられていないスニペットをたくさん配置するのは面倒なことのように思えます。なぜなら、実際のビューでは、アイテム全体を順序付けられた構造化された形式で含む100%すぐに使用できるJSONオブジェクトを表示できなかったからです。

ここに画像の説明を入力してください

実際の問題を伝えることができたと思います。私は、どの解決策が自分に適しているか、どの問題を克服しやすいかを判断しようとしています。最初のソリューションは、ストレージとクエリの点でよりきれいなソリューションであると思いますが、2番目のソリューションは、ビュー内のより優れたキー管理によって解決できるより実用的なソリューションです(私はまだキーの原則に完全には精通していません)。

よろしくお願いします:)

4

1 に答える 1

8

2番目のオプションを選択してください。対立に対処しなければならないよりもはるかに簡単です。データを構造化する方法のサンプルドキュメントを次に示します。

{
   _id: 12345,
   type: 'question',
   slug: 'couchdb-single-document-vs-joining-documents-together',
   markdown: 'Im tryting to decide the best approach for a CouchApp (no middleware). Since there are similarities to...' ,
   user: 'roman-geber',
   date: 1322150148041,
   'jquery.couch.attachPrevRev' : true
}
{
   _id: 23456,
   type: 'answer'
   question: 12345,
   markdown: 'Go with your second option...',
   user : 'ryan-ramage',
   votes: 100,
   date: 1322151148041,
   'jquery.couch.attachPrevRev' : true
}
{
   _id: 45678,
   type: 'comment'
   question: 12345,
   answer: 23456,
   markdown : 'I really like what you have said, but...' ,
   user: 'somedude',
   date: 1322151158041, 
   'jquery.couch.attachPrevRev' : true
}

それぞれのリビジョンを保存するには、編集中のドキュメントに古いバージョンを添付ファイルとして保存します。couchdbにjqueryクライアントを使用する場合は、jquery.couch.attachPrevRev=trueを追加することで無料で入手できます。jchrisによるCouchDBのバージョン管理ドキュメントを参照してください

このようなビューを作成します

fullQuestion : {
   map : function(doc) {
       if (doc.type == 'question') emit([doc._id, null, null], null);
       if (doc.type == 'answer')   emit([doc.question, doc._id, null], null);
       if (doc.type == 'comment')  emit([doc.question, doc.answer, doc._id], null) ;
   }
}

そして、このようにビューをクエリします

http://localhost:5984/so/_design/app/_view/fullQuestion?startkey=['12345']&endkey=['12345',{},{}]&include_docs=true

(注:このクエリはURLエンコードされていませんが、読みやすくなっています)

これにより、ページを作成するために必要な質問に関連するすべてのドキュメントが表示されます。唯一のことは、それらが日付でソートされないということです。クライアント側で(javascriptで)並べ替えることができます。

編集:ビューとクエリの代替オプションは次のとおりです

あなたのドメインに基づいて、あなたはいくつかの事実を知っています。質問が存在する前に回答が存在できず、回答が存在する前に回答に対するコメントが存在できないことを知っています。それでは、物事の順序を尊重して、表示ページの作成を高速化する可能性のあるビューを作成しましょう。

fullQuestion : {
   map : function(doc) {
       if (doc.type == 'question') emit([doc._id, doc.date], null);
       if (doc.type == 'answer')   emit([doc.question, doc.date], null);
       if (doc.type == 'comment')  emit([doc.question, doc.date], null);
   }
 }

これにより、関連するすべてのドキュメントがまとめられ、日付順に並べられます。これがサンプルクエリです

http://localhost:5984/so/_design/app/_view/fullQuestion?startkey=['12345']&endkey=['12345',{}]&include_docs=true

これにより、必要なすべてのドキュメントが古いものから新しいものの順に返されます。これで、次のように、親オブジェクトが子オブジェクトの前にあることがわかっているので、結果を圧縮できます。

function addAnswer(doc) {
   $('.answers').append(answerTemplate(doc));
}

function addCommentToAnswer(doc) {
   $('#' + doc.answer).append(commentTemplate(doc));
}

$.each(results.rows, function(i, row) {
   if (row.doc.type == 'question') displyQuestionInfo(row.doc);
   if (row.doc.type == 'answer') addAnswer(row.doc);
   if (row.doc.type == 'comment') addCommentToAnswer(row.doc)
})

したがって、クライアント側の並べ替えを実行する必要はありません。

お役に立てれば。

于 2011-11-24T16:30:41.250 に答える