13

私はMongoDb / Mongooseにはかなり慣れていませんが、SQL ServerまたはOracleに慣れています。

イベント用のかなり単純なスキーマがあります。

EventSchema.add({
  pkey: { type: String, unique: true },
  device: { type: String, required: true },
  name: { type: String, required: true },
  owner: { type: String, required: true },
  description: { type: String, required: true },
});

私はそれを行う2つの方法を示すMongoose Indexesを見ていました.フィールド定義を使用しました.

また、POST を受け取り、このコレクションに対して create を呼び出してレコードを挿入する、非常に単純な API もあります。

同じ pkey を持つレコードの挿入が発生しないこと、および unique:true が機能していることを確認するテストを作成しました。配列に読み取った一連のイベントが既にあるので、最初のイベントをもう一度 POST して何が起こるかを確認します。mongo DB が E11000 重複キー エラーをスローすると予想していましたが、これは起こりませんでした。

var url = 'api/events';
var evt = JSON.parse(JSON.stringify(events[0]));

// POST'ed new record won't have an _id yet 
delete evt._id;

api.post(url)
   .send(evt)
   .end(err, res) {
     err.should.exist; 
     err.code.should.equal(11000); 
   }); 

テストは失敗し、エラーはなく、重複レコードが挿入されます。

コレクションを見ると、同じ pkey を持つ 2 つのレコードが表示されます (元のレコードとテスト用に投稿したコピー)。2 番目のレコードの作成日は最初のレコードと同じですが、変更日は後であることに気付きました。

(mongo は私が最新の変更されたバージョンのレコードを使用することを期待していますか???、URL が異なり、ID も異なります)

[ { _id: 2,
    pkey: '6fea271282eb01467020ce70b5775319',
    name: 'Event name 01',
    owner: 'Test Owner',
    device: 'Device X',
    description: 'I have no idea what\'s happening',
    __v: 0,
    url: '/api/events/2',
    modified: '2016-03-23T07:31:18.529Z',
    created: '2016-03-23T07:31:18.470Z' },
  { _id: 1,
    pkey: '6fea271282eb01467020ce70b5775319',
    name: 'Event name 01',
    owner: 'Test Owner',
    device: 'Device X',
    description: 'I have no idea what\'s happening',
    __v: 0,
    url: '/api/events/1',
    modified: '2016-03-23T07:31:18.470Z',
    created: '2016-03-23T07:31:18.470Z' }
]

私は、フィールド定義の unique: true がmongo dbに、これがあなたが望んでいたものであり、mongoが保存時にそれを強制したことを伝えた、または何かを誤解しただけだと思っていました...

SQL 用語では、URL ルックアップで使用できるキーを作成しますが、重複挿入を防ぐために一意の複合インデックスを作成できます。イベントのどのフィールドがレコードを一意にするかを定義できる必要があります。これは、フォーム データ POST でフォームの送信者が次に使用可能な _id 値を持っていないため、_id を使用するためです (「mongoose-auto-increment」によって行われます)。 ) のように、アプリの他の部分からの URL の使用がクリーンになるようにします。

/events/1

次のような複合値の完全な混乱ではありません

/events/Event%20name%2001%5fDevice%20X%5fTest%20Owner

コーディングを開始しようとしているので、今のところ、この単一の文字列に対して簡単なテストを作成しましたが、実際のスキーマにはさらにいくつかのフィールドがあり、一意性のためにそれらの組み合わせを使用します。テスト、フィールド、コードを追加する前に、動作をテストしてください。

2番目のレコードが実際に挿入されないようにするために私がすべきことはありますか?

4

5 に答える 5

4

データベースにいくつかのレコードを挿入した後、(スキーマ レベルで) 一意のインデックス作成を行ったようです。

重複を避けるために、以下の手順に従ってください -

1) データベースをドロップします。

$モンゴ

> use <db-name>;

> db.dropDatabase();

2) スキーマ レベルまたはデータベース レベルでインデックス作成を行う

 var EventSchema = new mongoose.Schema({
      pkey: { type: String, unique: true },
      device: { type: String, required: true },
      name: { type: String, required: true },
      owner: { type: String, required: true },
      description: { type: String, required: true },
    });

同じ pKey 値を持つレコードの重複挿入を回避します。

インデックスを確保するには、 command を使用します db.db_name.getIndexes()

お役に立てば幸いです。ありがとうございました

于 2017-05-30T15:11:50.403 に答える
2

mongoose.connect で {useCreateIndex: true} を追加します。

このように見えるはずです

mongoose.connect(uri, {
useNewUrlParser: true, 
useUnifiedTopology: true, 
useCreateIndex: true
})
于 2021-02-08T03:43:45.253 に答える
1

OK、2 番目の挿入がポストされる前にインデックスを更新する時間がないことに関係しているようです (私のテスト スイートではそれらの間に 9 ミリ秒しかないため)。

  • 「インデックス」を待っている挿入について何かをする必要があります
  • API のすべてのユーザーが Web アプリケーションであるとは限らないため、API 側である必要があります。

制約に関する他の SO 記事もいくつか見つけました。

マングース固有: true は機能しません

Mongoose / MongoDB で一意のインデックスが機能しない

Date フィールドに対する MongoDB/Mongoose の一意の制約

于 2016-03-23T09:41:58.953 に答える