2016-03-23 22 views
1

私はMongoDb/Mongooseをかなり使い慣れており、SQL ServerやOracleによく慣れています。Mongooseでの重複レコードの防止

イベント用のスキーマはかなり単純です。私はそれを行うための2つの方法を示しMongoose Indexesを見ていた

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 }, 
}); 

、私はフィールド定義を使用しました。

私はまた、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番目のレコードの作成日が最初のものと同じで、後のものが変更されたものであることに気付きます。

(モンゴ私は、最新の修正版レコードを???使用することを期待して、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' } 
] 

私はユニークなことを想定していた:真がフィールド定義にモンゴに語りましたあなたが望んでいたこととmongoがあなたのためにそれを強制的に実施したのか、それともちょうど何かを誤解したかもしれません...

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

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

のように、

/events/1 

なく複合値の完全な混乱のように、きれいになるように)私はコーディングを開始するちょうど約よ今のところ、この単一の文字列に対して単純なテストを書いただけですが、実際のスキーマにはさらにいくつかのフィールドがあり、それらの組み合わせを一意に使用します。私は実際に最初のテス私はより多くのテスト、より多くのフィールドとより多くのコードを追加し始めます。

2番目のレコードが実際に挿入されないようにするために何かする必要がありますか?

+0

おそらく読んでいて、 "madatory"の '_id'フィールドが実際にプライマリキーであることに気づいたはずです。デフォルト値ではない数値があるので(ここでは、おそらくインポートされた数値の主キーです)、ここで何かしたことがあります。実際に "ユニークなプライマリキー"という別の値がある場合は、代わりに '_id'に入れておくべきです。少しの読書は多くの問題を救うでしょう。 –

+1

いくつかのものを読んでみると、あまり参考にならない...、私は "mongoose-auto-increment"を含んでいますが、明らかに_idを作成して、それぞれの保存時に1ずつ上がります。 _idは、/ events /:idに対して一意で有用な場合がありますが、これはレコードを一意にするものではなく、イベント(追加される)のフィールドの複合コンビネーションによって決まります。私は、インデックスに複数の値を追加して全体をコーディングする前に、スキーマの1つのフィールドで簡単なテストを実行するかどうかを確認したかったのです。複合キーの値は、URLにイベント/ {:horible_key}を与えます –

答えて

0

OK、それはインデックスが(私のテストスイートで、それらの間の唯一て9msがあるとして)第二のインサートが掲載される前に更新する時間を持っていないとは何かを持っているように見えます。

  • は、「インデックス」
  • を待っ挿入について何かをする必要がAPI側にする必要があるとして、APIのすべてのユーザーが

Webアプリケーションですではない、私はまた、制約に関するいくつかの他のSOの記事を見つけました:

mongoose unique: true not work

Unique index not working with Mongoose/MongoDB

MongoDB/Mongoose unique constraint on Date field

0

追加:

EventSchema.index({ pkey: 1 }, { unique: true }); 
+0

OK - それを行いましたが、結果は同じです。同じキー値を挿入した2つのレコードを取得しました...クイックテストとして、あなたが私にそれを置き換えたいかどうか確信が持てませんでしたが、フィールド定義からもユニークですが、これも2つのレコードを挿入します。:( –

0

dbにレコードを挿入した後にユニークなインデックス作成(スキーマレベルで)したようです。

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

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値でレコードを重複して挿入しないようにします。

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

これが役に立ちます。

関連する問題