7

私はそのようなスキーマを持っています:

class Schemas

  constructor: ->
    @mongoose = require 'mongoose'
    @schema = @mongoose.Schema

    @EmployeeSchema = new @schema
      'firstname': { type: String, required: true }, 
      'lastname': { type: String, required: true }, 
      'email': { type: String, required: true, index: { unique: true }, validate: /\b[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}\b/ },
      'departmentId': { type: @schema.ObjectId, required: true }
      'enddate': String,
      'active': { type: Boolean, default: true } 

    @EmployeeSchemaModel = @mongoose.model 'employees', @EmployeeSchema

    @DepartmentSchema = new @schema
      'name': { type: String, required: true, index: { unique: true } }
      'employees' : [ @EmployeeSchema ]

    @DepartmentSchemaModel = @mongoose.model 'departments', @DepartmentSchema

だから私は内部employeesのドキュメントの配列に住んでいますemployeedepartment

配列にdepartment多数のemployeeドキュメントが保存されているドキュメントがいくつかあります。employees

次に、新しいものを追加しましたdepartmentが、含まれていませんでしemployeesた。department次に、を使用せずに別のフィールドを追加しようとするとemployees、Mongooseは必須フィールドであるフィールドのを生成します。このフィールドは必須であり、一意である必要があります。Duplicate key erroremployee.emailemployee.email

とにかくこれの周りにありますか?

4

3 に答える 3

6

同等のcoffeescriptを使用してMongooseデバッグログを有効にすると、mongoose.set('debug', true);何が起こっているかを確認できます。

DEBUG: Mongoose: employees.ensureIndex({ email: 1 }) { safe: true, background: true, unique: true }      
DEBUG: Mongoose: departments.ensureIndex({ name: 1 }) { safe: true, background: true, unique: true }      
DEBUG: Mongoose: departments.ensureIndex({ 'employees.email': 1 }) { safe: true, background: true, unique: true }  

(単なる参照ではなく)EmployeeSchemaemployees配列に完全を埋め込むことにより、との両方に一意のインデックスを作成することになります。DepartmentSchemaObjectIdemployees.emaildepartment.employees.email

departmentしたがって、従業員なしで新しいメールを作成するdepartment.employees.emailと、一意性の限り、インデックス内の未定義の電子メールケースが「使い果たされ」ます。したがって、2回目にそれを実行しようとすると、その一意の値がすでに取得され、が取得されますDuplicate key error

これに対する最善の修正は、おそらく、完全なオブジェクトではなく、従業員へDepartmentSchema.employeesの参照の配列に変更することです。ObjectIdその後、インデックスはemployeesそれが属するコレクションに残り、データを複製したり、不整合の機会を作成したりすることはありません。

于 2012-09-20T12:47:23.340 に答える
1

これらの参考資料を確認してください。

http://docs.mongodb.org/manual/core/indexes/#sparse-indexes

mongoDB / mongoose:nullでない場合は一意(具体的にはJohnnyHKの回答)

つまり、Mongo 1.8以降、sparseインデックスと呼ばれるものを定義できます。これは、値がnullでない場合にのみ一意のチェックを開始します。

あなたの場合、あなたは望むでしょう:

@EmployeeSchema = new @schema
  'firstname': { type: String, required: true }, 
  'lastname': { type: String, required: true }, 
  'email': { type: String, required: true, index: { unique: true, sparse: true }, validate: /\b[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}\b/ },
  'departmentId': { type: @schema.ObjectId, required: true }
  'enddate': String,
  'active': { type: Boolean, default: true }

sparse: trueEmployeeSchemaのemail属性のインデックスに追加されていることに注意してください。

https://gist.github.com/juanpaco/5124144

于 2013-03-09T13:18:48.920 に答える
0

サブドキュメントの個々のフィールドに一意のインデックスを作成できないようです。Mongoシェルのdb.collection.ensureIndex関数はそれを可能にするように見えますが、個々のフィールドではなく、サブドキュメント全体の一意性をテストします。

サブドキュメントの個々のフィールドにインデックスを作成できますが、一意にすることはできません。

于 2012-09-20T09:46:33.497 に答える