1

だから、私は問題に遭遇しています。提供されているデータに基づいて、「きれいな」URL を生成しようとしているサーバーがあります。議論のために、ブログ記事のタイトルを言ってみましょう。リソースを適切に表すために、この URL は明らかに一意である必要があります。間違っていたら訂正してください..しかし、これはMongoDBの単純な問題ではありませんか?

最初に、ある種の自動インクリメントフィールドをグーグルで検索しました。これは私が期待したものを返しましたが、明らかな問題がありました.. 10genはそれに対してアドバイスしています.

警告 通常、MongoDB では、 _id フィールドや任意のフィールドに自動インクリメント パターンを使用しません。これは、多数のドキュメントを含むデータベースに対応しないためです。通常、_id にはデフォルト値の ObjectId の方が適しています。

太字のテキストに注意してください。10gen では、フィールドをインクリメントすることはお勧めしません。

では、問題に戻ります。サーバーに投稿のタイトルを渡し、投稿を作成したい場合、タイトルが一意のタイトルに自動的に変更されることを期待しています。たとえば、タイトルが の投稿を 3 つ作成した場合、サーバーに、、 のfooURL を作成してもらいます。一意の追加の任意の形式である可能性がありますが、ここでのポイントは、サーバーが一意の URL を作成するという汚い作業を処理していることです。単純に失敗してユーザーに一意の URL を考え出させようとするのではありません。/foo/foo1/foo2

そうは言っても、これは「MongoDBの方法」でどのように行われますか? 10genはインクリメントしないようにアドバイスています.基本的に私が見つけることができる唯一のユニークな文字列は ですが、ObjectIDほとんど/foo50bbe1573b60ff0000000002「きれい」ではありません. を使用せざるを得ない場合は/foo50bbe1573b60ff0000000002、単に使用することもできます/50bbe1573b60ff0000000002。「かわいい」は、最初の 5 文字の後に消えてしまいました。

では、MongoDB に適した方法でこの問題を処理する方法についての考えや意見はありますか?

考えられる答え: 恐ろしい解決策の 1 つは、一意のパスまでドキュメントの作成を繰り返すことですが、最大 X 回です。例えば、

  1. あなたはタイトルでそれを書いてみることができます
  2. それが失敗した場合は、タイトルと objectid の増分値(00002 など)を付けて書き込みます。
  3. それが失敗した場合は、オブジェクト ID 全体を書き込んでください。とにかく、この時点ですでに負けています。

考えられる答え: もう 1 つの考えられる答えは、単純に 10gen が推奨していることを実行して、インクリメント フィールドを作成することです。

上記の2つのソリューションのうち、それぞれがさまざまな方法でより効率的であると確信しています。たとえば、一意のフィールドが一意である可能性が非常に高い場合、たとえば40文字のユーザー入力データの場合、ソリューション1がおそらく最適です。4 人のキャラクターを扱っている場合、糖蜜のように遅くなる可能性があります。

編集:より良い回答 2つの組み合わせが最適だと思います。「元の」URL (例: /foo)のコレクションと、それらが書き込まれた回数のカウントがあります。カウントをターゲット URL に追加すると、一意の URL が得られます。これは、10gen が推奨しているパフォーマンスの問題とのバランスを取ると同時に、増加ももたらすと考えています。

4

1 に答える 1

4

10gen は、ある種の悲観的な同時実行性を設定したり、サーバー側の JavaScript を使用してコレクション全体の現在の最大キーを見つけたり、それをインクリメントして新しい _id を返したりすることに対して警告しています。MongoDB は、しばしばファイア アンド フォーゲットの挿入/更新に依存する巨大なコレクション用に設計されています。あなたが説明しているアプリケーションの性質上、これらのどれも障害にはなりません (10gen のアドバイスよりもはるかに重要なのは、問題のドメインに関する知識と、これが警告を与えたアイテムとどのように相互作用するかということです)。

10gen のアドバイスに反しないより良い方法は、投稿の他の属性 (ユーザー名、作成日時など) から URL を作成することです。

ブログ投稿の例では、次のような URL パスがある場合があります。

/posts/userName/2013/3/5/私の投稿のタイトル

表示しているリソースの属性に基づいて実際のスキームを決定する必要がありますが、それは良い出発点です。この例では、1 人のユーザーがまったく同じタイトルで同じ日に 2 つの投稿を作成しない限り、一意の URL を確保することに問題はありません。この場合のドキュメントは次のようになります。

{ _id: ObjectId(...), userName: "userName", dateCreated: ISODate("2013-03-05"), title: "私の投稿のタイトル", body: "..." }

一意のインデックスをオンにすると{dateCreated: -1, userName: 1, title: 1}(これにより、ユーザーによる投稿の並べ替えと順序付けも適切に設定されます)。

于 2013-03-06T01:57:54.277 に答える