programing

mongoDB/mongoose: 늘이 아닌 경우 고유

newstyles 2023. 2. 23. 22:10

mongoDB/mongoose: 늘이 아닌 경우 고유

고유한 컬렉션 엔트리를 강제 적용할 방법이 있는지 알고 싶습니다만, 엔트리가 null이 아닌 경우에만 가능합니다.e 샘플 스키마:

var UsersSchema = new Schema({
    name  : {type: String, trim: true, index: true, required: true},
    email : {type: String, trim: true, index: true, unique: true}
});

이 경우 '이메일'은 필수는 아니지만 '이메일'이 저장되었을 경우 이 엔트리가 (데이터베이스 수준에서) 고유함을 확인하고 싶습니다.

빈 엔트리는 'null' 값을 얻을 수 있기 때문에 모든 엔트리는 'unique' 옵션을 사용하여 크래시됩니다(이메일이 없는 다른 사용자가 있는 경우).

지금은 응용 프로그램 차원에서 해결 중이지만 해당 DB 쿼리를 저장하고 싶습니다.

고마워

MongoDB v1.8+ 에서는, 다음의 설정을 실시하는 것으로, 일의의 값을 보증할 수 있습니다만, 필드 없이 복수의 문서를 허가할 수 있습니다.sparse옵션을 true로 설정합니다.예:

email : {type: String, trim: true, index: true, unique: true, sparse: true}

또는 셸:

db.users.ensureIndex({email: 1}, {unique: true, sparse: true});

고유하고 스파스한 인덱스로는 아직 여러 개의 문서를 사용할 수 없다는 점에 주의해 주십시오.email을 가진 필드null, 여러 개의 docs만,email들판.

http://docs.mongodb.org/manual/core/index-sparse/ 를 참조해 주세요.

dr;dr

예, 다음과 같은 필드가 설정된 여러 문서를 가질 수 있습니다.null또는 정의되지 않은 상태에서 고유한 "유일한" 값을 적용합니다.

요건:

  • MongoDB v3.2+
  • 구체적인 값 유형을 미리 알고 있어야 합니다(예: 항상,string또는object그렇지 않을 때는null).

자세한 내용에 관심이 없는 경우,implementation부분.

긴 버전

@Nolan의 답변을 보완하기 위해 MongoDB v3.2부터는 필터 식과 함께 부분 고유 인덱스를 사용할 수 있습니다.

부분 필터 식에 제한이 있습니다.다음 항목만 포함할 수 있습니다.

  • 등식(예: 필드: 값 또는 값 사용)$eq오퍼레이터)
  • $exists: true표현,
  • $gt,$gte,$lt,$lte표현.
  • $type표현.
  • $and최상위 수준의 연산자만 해당

이것은 사소한 표현이{"yourField"{$ne: null}}사용할 수 없습니다.

그러나 필드에서 항상 같은 유형을 사용하는 경우 식을 사용할 수 있습니다.

{ field: { $type: <BSON type number> | <String alias> } }

MongoDB v3.6에서는 어레이로 전달할 수 있는 여러 유형을 지정할 수 있는 지원이 추가되었습니다.

{ field: { $type: [ <BSON type1> , <BSON type2>, ... ] } }

즉, 이 값은 여러 유형의 값을 허용하지만 그렇지 않을 경우 여러 유형의 값을 지정할 수 있습니다.null.

따라서, 만약 우리가 그것을 허용하고 싶다면,email다음 예제의 필드에 다음 중 하나를 적용합니다.string예를 들어,binary data값, 적절한$type을 사용하다

{email: {$type: ["string", "binData"]}}

실행

몽구스

mongoose 스키마로 지정할 수 있습니다.

const UsersSchema = new Schema({
  name: {type: String, trim: true, index: true, required: true},
  email: {
    type: String, trim: true, index: {
      unique: true,
      partialFilterExpression: {email: {$type: "string"}}
    }
  }
});

또는 컬렉션에 직접 추가합니다(네이티브 node.driver 사용).

User.collection.createIndex("email", {
  unique: true,
  partialFilterExpression: {
    "email": {
      $type: "string"
    }
  }
});

네이티브 mongodb 드라이버

사용하고 있다

db.collection('users').createIndex({
    "email": 1
  }, {
    unique: true,
    partialFilterExpression: {
      "email": {
        $type: "string"
      }
    }
  },
  function (err, results) {
    // ...
  }
);

몽고드 셸

사용:

db.users.createIndex({
  "email": 1
}, {
  unique: true, 
  partialFilterExpression: {
    "email": {$type: "string"}
  }
})

하면 여러 될 수 있습니다.null전자 메일 또는 전자 메일 필드가 전혀 없지만 동일한 전자 메일 문자열이 없습니다.

이 토픽을 조사하고 있는 사람들의 간단한 업데이트입니다.

선택한 답변은 작동하지만 대신 부분 인덱스를 사용하는 것이 좋습니다.

버전 3.2에서 변경: MongoDB 3.2에서 MongoDB는 부분 인덱스를 생성할 수 있는 옵션을 제공합니다.부분 인덱스는 스파스 인덱스의 기능을 제공합니다.MongoDB 3.2 이후를 사용하는 경우, 부분 인덱스는 스파스 인덱스보다 우선해야 합니다.

부분 인덱스에 관한 기타 doco : https://docs.mongodb.com/manual/core/index-partial/

실제로 "이메일" 필드가 존재하지 않는 첫 번째 문서만 정상적으로 저장됩니다.「이메일」이 없는 경우는, 다음의 코드 스니펫을 참조해 주세요.이 때문에, MongoDB의 「Unique Indexs」및 「Missing Keys」에 관한 공식 메뉴얼을 참조해 주세요.

  // NOTE: Code to executed in mongo console.

  db.things.ensureIndex({firstname: 1}, {unique: true});
  db.things.save({lastname: "Smith"});

  // Next operation will fail because of the unique index on firstname.
  db.things.save({lastname: "Jones"});

정의에 따르면 고유 인덱스는 한 번만 값을 저장할 수 있습니다.null을 이러한 값 중 하나로 간주할 경우 한 번만 삽입할 수 있습니다!어플리케이션 레벨에서 확실하게 검증함으로써 접근법이 정확합니다.그렇게 하면 된다.

이 http://www.mongodb.org/display/DOCS/Querying+and+nulls도 읽어보실 수 있습니다.

언급URL : https://stackoverflow.com/questions/7955040/mongodb-mongoose-unique-if-not-null