1

node.js と MongoDB を使用して RESTful Web アプリケーションを構築しています。

Person モデルがあります

Person
  id:         '12345'
  name:       'John'
  likes:      [ {id: '54321', name: 'Mary'} ]
  isLikeydBy: []


Person
  id:         '54321'
  name:       'Mary'
  likes:      []
  isLikeydBy: [ {id: '12345', name: 'John'} ]

「いいね」と「isLikedBy」の関係をモデル化する最良の方法は何ですか? 私は MongoDB を使用しているので、1 人の人物に関するすべてのデータを取得するために必要なデータベースへのアクセスは 1 回だけなので、これは関係をモデル化するための良い方法だと思いました。

この関係の REST API を作成するにはどうすればよいですか? 「ジョン」が「メアリー」をもう好きでなくなったらどうしますか。サーバーは次の put リクエストのみを受け取ります。

  Person
  id:         '12345'
  name:       'John'
  likes:      []
  isLikeydBy: []

ただし、サーバーは「Mary」も更新する必要があります。これは、彼女が「John」に好かれなくなったためです。(MongoDB はトランザクションを直接サポートしておらず、自分で実装する必要があることを知っています。)

私のアイデア:

1. Person (「likes」および「isLikedBy」フィールド) が更新されるたびに、データベースからこの人物を取得し、「likes」および「isLikedBy」フィールドをリクエストと比較します。このアプローチにはいくらかのオーバーヘッドがあり、それが RESTful API の精神に沿っているかどうかもわかりません。

2.クライアントに、元の「likes」フィールドと「isLikedBy」フィールドの両方と、新しく更新されたフィールド (または差分のみ) を送信させます。クライアントは、どのデータが最後にサーバーに正常に保存されたかを認識しなければならないため、これは RESTful 設計とはかけ離れているように見えます。

3.関係情報を含む別のオブジェクトを作成します (3 つのフィールド: id、me、whoILike)。しかし、これは、個人に関するデータを取得するたびに、個人用と関係用の 2 つのクエリが必要になり、データを 1 つのオブジェクトに結合することを意味します。

私は何をすべきか?

4

1 に答える 1

2

私の会社でも、Mongo を使用していいねを追跡する際に、この同じ問題に取り組んできました。

多くの議論の末、いいねの数をエンティティに保存することにしました。この場合は、いいねを人に保存します。

オプションに関する意見:

  1. 追加のクエリを実行する際のオーバーヘッドは、おそらく悪い考えです。特に、「好き」なものは軽量な操作としてユーザーに見られているためです。言い換えれば、ユーザーが大量のもの、つまり大量の書き込みを好むことに気付くかもしれません。この場合、すべての書き込みには追加の読み取りが 1 つまたは 2 つ含まれています。

  2. これは開発者にとって大変な作業であり、間違いを犯しやすいです。

  3. 私はそれでいいと思いますが、私はその人と一緒にいいねを保存することを好みます. あなたが言ったように、モンゴは結合が苦手です。

like/liked by フィールドを person ドキュメントに保存する必要があると思います。私が変更する唯一のことは、REST 呼び出しが行われることです。

たぶん次のようなもの:

PUT http://www.rest.com/person/123/likes/456

これは、「人 123 が 456 を気に入っています」となります。その後、REST 呼び出しにより、データが更新されていることが確認されます。Person 123 オブジェクトPerson 456 オブジェクトを更新します。

次のようなものを削除するには:

DELETE http://www.rest.com/person/123/likes/456

誰かが REST 呼び出しを行うたびに、更新によってドキュメント全体が更新される必要はないことに注意してください。変更されたいいね! を使用して、個人文書を部分的に更新できます。ドキュメント内の配列を簡単に追加/削除することもできます。

于 2013-02-03T04:33:55.737 に答える